Need to create a h.264/or/h.265 video of a giant timer. - Page 1
Forum section: electronics / general

author: BrianHG
author_rank: Super Contributor
timestamp: October 06, 2023, 12:41:15 am
content: And my project continues...A need to create 4 videos of a 480p .mp4 or .mkv video of a giant timer. The giant timer will have +/- minutes, seconds with one decimal point tenths of a second. The 4 videos will need to contain:1) A 15 second countdown in blue with the last 5 seconds in red, then a 3 minute count up in yellow with the last minute in red, then a 2 minute count down in blue.2) Same as #1, but replace the 3 minutes count up with 4 minutes.3) Same as #1, but replace the 3 minutes count up with 5 minutes.4) Same as #1, but replace the 3 minutes count up with 6 minutes.The timer will be full screen sized, with a smaller title printed above.Now, none of my computers are fast enough for screen capture or any real-time video encoding. I guess what I am looking for is something like video titling software which can be setup to create a customized stop-watch with just a black background and render and encode a video for me. I already have utility which can take my h.264/265 videos and replace the audio track with the sound samples I created to finish the video.Is there any public domain/free text video presentation programs which can do this in windows 7?

author: mariush
author_rank: Super Contributor
timestamp: October 06, 2023, 04:21:36 am
content: You can use virtualdub - this improved version :https://sourceforge.net/projects/vdfiltermod/- to capture the desktop using a low cpu usage / lossless compression codec like MagicYUV (the free version is fine ) and then resize and compress to h264You could "generate" the video in Virtualdub by creating a blank video with the duration you desire and you could create a "subtitle" file with your timer and use a subtitle filter to put the timer on the blank video. Then you could compress it.srt subtitles are very easy to programatically make

author: BrianHG
author_rank: Super Contributor
timestamp: October 06, 2023, 04:34:13 am
content: Quote from: mariush on October 06, 2023, 04:21:36 amHmmm. I wonder if .srt can display a font as large as the screen. Maybe. What I would have to do is made a blank video, Create a .srt. Then play that back to be re-transcoded so that I convert the soft-subtitle to a hard-sub-title and re-encode so that my final video does not have any subtitle stream, but the text as part of the video picture.This will take more than a day of fidling to get it to function right. I'll reserve your idea as a last resort while I hope someone offers me a better solution over the next day.Thanks mariush, at least I have an all else fails solution as I have used virtualdub & FDDShow with avisynth scripts, so at least I know my way around.

author: mariush
author_rank: Super Contributor
timestamp: October 06, 2023, 04:37:16 am
content: You can use Virtualdub to capture a 640x480 region of your screen, a black rectangle, your desktop or black something in an application (or whatever color). Then load that video in Virtualdub and cut it to your length and put the subtitle filter on it.There's also filters for just placing text on the movie, or you can put the text as a logo with transparent background.Alternatively, you could use Python or PHP or whatever to generate one bitmap picture for every second and then load the image sequence in virtualdub as a 1fps movie , and tell virtualdub to resize it to 30-60 fps for every bitmap loaded. ( if you want decimals after seconds you'd probably want to generate 10 bitmaps per second so you'd treat it as a 10fps movie and from settings change it to generate 3-6 frames for every input bitmap, to get 30-60 fps movie)in php this is a 10-15 minute job ... create true color bitmap, select font that's monospaced (so that digits don't move all over the screen horizontally) , print timer at position in picture, print your title text with another font if you desire , save picture as bitmap or png or gif, close bitmap , repeat with next frame.

author: Whales
author_rank: Super Contributor
timestamp: October 06, 2023, 05:37:04 am
content: Generate the frames as still images, then use ffmpeg to convert them into the final video file. This way the output is completely predictable, you can use any method of generating the source images and you and don't need to run a screencap in realtime.For generating the images: use whatever language you're familiar with. I'd go for shell scripts and ImageMagick. Other people will prefer python libs. I'm sure the Windows-centric options of visual basic and dotnet will let you save pngs of a GUI.

author: mariush
author_rank: Super Contributor
timestamp: October 06, 2023, 07:32:28 am
content: Here's example of PHP script that generates images :Uses only GD which should be enabled by default, so you can just run php.exe script.phpFont files should be in same folder as the script, I copied consolas from C:\Windows\Fonts into the folder where the script is, the filename was consola.ttfbut you can download monospaced ttf fonts from a site like dafont.com if you want and edit the script to use a different fontCode:<?php// if filename is empty, output to browser// formats = bmp, png, giffunctioncreate_image($text,$filename="",$format="png") {// to display in browser page, tell browser it&#39;s an image not textif ($filename=="")header("Content-Type: image/png");$im= @imagecreatetruecolor(640,480) or die("Cannot Initialize new GD image stream");$text_color=imagecolorallocate($im,255,0,255);// magenta$back_color=imagecolorallocate($im,0,0,0);// black$ret=imagefill($im,1,1,$back_color);// floodfill the image with black// image, size, angle, x, y, color, font_filename, text , optionsimagettftext($im,70,00,10,250,$text_color,__DIR__."/consola.ttf",$text);// add your own line of text with another font here if you wantif ($filename=="") {// dump the binary png image to the browserimagepng($im);} else {if ($format=="bmp")imagebmp($im,$filename);if ($format=="png")imagepng($im,$filename);if ($format=="gif")imagegif($im,$filename);}imagedestroy($im);}$ret=create_image("00:00:00.100");// comment the line above and remove the die(); below if you want to run the loop to generate n images.die();// example of making image sequence :$counter=0;$hh=0;$mm=0;$ss=0;$ms=0;$picturecount=1000;// seconds x 10,for ($i=0;$i<$picturecount;$i++) {// hh:mm:ss:ms00$text=str_pad($hh,2,"0",STR_PAD_LEFT) .":".str_pad($mm,2,"0",STR_PAD_LEFT) .":".str_pad($ss,2,"0",STR_PAD_LEFT).".".str_pad($ms,3,"0",STR_PAD_RIGHT);// create image and auto save it as c:/temp/img00000000.png (8 digits)$result=create_image($text,"c:/temp/img".str_pad($counter,8,"0",STR_PAD_LEFT).".png");$counter++;$ms++;// crude but it works.if ($ms==10) {$ms=0;$ss++;}if ($ss==60) {$ss=0;$mm++;}if ($mm==60) {$mm=0;$hh++;}}?>Didn't test the loop and saving to disk, but it should work. If it doesn't should be fairly easy to debug.output to browser is as the attached image.. made the text on purpose magenta, to be easier to see. colors can be changed easily by entering the rgb values.

author: BrianHG
author_rank: Super Contributor
timestamp: October 06, 2023, 03:57:32 pm
content: Quote from: mariush on October 06, 2023, 07:32:28 am@mariush, thanks for your code. Now, I just need to learn how to install and run python. To think I was going to do this in FreeBasic, though, it internally has built in saving as .bmp, but .png would save disk space by a ton.I'll probably generate 720x480, 10fps and encode, or 1 .png frame every 10th of a second and have virtual dub do a conversion to the standard 23.976fps and resample my audio to 48khz before encoding. (Being time critical and since I cannot predict which player will be used on the other side, I need to use broadcast industry standard frame & sample rates to guarantee lip-sync.)

author: mariush
author_rank: Super Contributor
timestamp: October 06, 2023, 06:03:01 pm
content: The code above is in PHP which is a web scripting language, but which can also be run in command line locally. No need for Python.In Windows you can just download and unpack the zip in a folder, for example c:\temp\phpYou can download it from here :https://windows.php.net/download#php-8.2- either the Thread Safe or Non Thread Safe versions will work, doesn't matter in this context.Optionally you may need to download and install the visual C++ runtime (links are on the left, on the sidebar)Once you unpack it, you can just copy PHP scripts in the same folder where php.exe is, open a console window in that folder and just type php.exe filename.php to run the script and see the output in console window.You may also need to rename php.ini-production or php.ini-development to php.ini - development is just more verbose, will show warnings and error messages on screen if you write a php script badly.You can run a temporary web server if you want to run scripts in browser. For example, make a folder c:\temp\website , and run the command in the folder where php.exe is :php.exe -S localhost:9999 -t c:/temp/website/I like to use / instead of \ because it avoids oddities like when you type a path in PHP script as a string variable "C:\temp" and you forget that if you use double quotes, PHP treats \t as tab character so you actually need to enter C:\\temp (and now \ is "escaped" or say 'c:\temp' (using single quotes disables string parsing) ... so it's just easier to use / instead, because Windows supports both.anyway, when you run that command now php will launch a web server on localhost, on port 9999 and will serve files from the c:\temp\website folder for as long as you leave that console window open - you can press Ctrl+C to stop it.So if you put script.php in that folder c:\temp\website and typehttp://localhost:9999/script.php,the script will run in the browser.Of course this assumes Windows firewall doesn't block php.exe from launching the server (give it permission when the firewall asks) and you don't have another server listening on port 9999 - if so pick any other number below 65500 something.

author: BrianHG
author_rank: Super Contributor
timestamp: October 09, 2023, 04:44:09 pm
content: Having a weird problem with .h265 VS .h264.I got my counter working cleanly in .h264 with an average bitrate of ~60 kilobits / second. (5min, 15 sec = 1827 kilobytes).When I try .h265 expecting a even better bitrate, no matter how I configure it, the bitrate is not only higher, but the video is chunky and sucks. Even worse, if I force the bitrate down to ~60kbps, the video is nothing but blobs and chunks. Is this normal? Going any further is probably a waste of my time and I guess I will live with ~60kbps.If anyone want's to play (see if you can get a better bitrate using a different compressor/settings) check out my link to the source .png animation frames and my 2 reference .h264 files. The link is safe, it is available for a week, and it is 39mb: (I added the 10fps, ~35kbps version as well, if it weren't for the VLC player bug...)https://we.tl/t-TQFvHVXuSd(The .png frames are at 10fps, but they I had to doubled them to 20fps when encoding so the VLC on the PC plays back the video smoothly. It's a VLC bug, it cant have too low fps video...)

author: mariush
author_rank: Super Contributor
timestamp: October 09, 2023, 08:27:12 pm
content: You would get much better compression if you use a different font for the timer. Use something more blocky, it's the curves of the digits (the sharp edge between color and black) that affect the compression.Like for examplehttps://www.dafont.com/led-calculator.fontorhttps://www.dafont.com/technology-2.fontorhttps://www.dafont.com/digital-display.fontIf you get the digits aligned at 8 pixel blocks you may get significant compression.On x264, I got it down to around 940 KB for the mp4 container but you start to notice artifacts at the edges of the digits. At around 1.2 MB they're gone.I've loaded the frames into Virtualdub and exported to raw videovideo > decode format > 4:2:0 (yv12) , colorspace rec.709 (default for hd), color range fulll 0..255)file > export > raw video ... 4:2:0 YCbCr planar, R.709 , 8-bit, Y:0-255, coaligned ... save with the extension YUVThen you can use command line encoders, I usedx264.exe --input-csp yv12 --input-range pc --input-res 1280x720 --fps 10 --profile main --preset placebo --tune animation --qp 35 -o test_qp35_main.mp4 test.yuvtune stillimage may give you better quality but a bit more disk space--profile main is on purpose, forcing x264 to use a simpler encoding format because with this content type there's really no quality gains by using profile high, so you save a few bits.--qp ## sets the quality level , it's like jpg quality, how much quality to trade ... 0 is lossless (never use, use 2-5 at most), 63 is worst qualityQP40 gives usable video at 930 KB (910 KB actual h264 stream), 3% is mp4 overhead...QP35 at 1.14 MB is very usable, barely any blurring at the edge.With x265 (hevc software encoder) the command line would be something like this :x265.exe --input test.yuv --fps 10 --input-res 1280x720 --videoformat ntsc --colorprim bt709 --range full --output-depth 8 --profile main --preset placebo --crf 1 -o test_crf1_hevc.mkvuse .h265 or mp4 as extension, i used .mkv out of habit and the attached file is not seekable (you can just remux it with mkvtoolnix to make it seekable)value after --crf sets the quality level , 0 being highest (lossless practically), 51 lowest qualityI would say you could probably go down to around crf 45 before you start to notice blockiness in the digits like in the attached example ... the attached file compresses to 560 KB (so around 150-200 KB is matroska container overhead)Code:x265.exe --input test.yuv --fps 10 --input-res 1280x720 --videoformat ntsc --colorprim bt709 --range full --output-depth 8 --frames 100 --profile main --preset placebo --crf 45 -o test_crf45_hevc.mkvyuv : 1280x720 fps 10000/1000 i420p8 frames 0 - 99 of 3146raw : output file: test_crf45_hevc.mkvx265 : HEVC encoder version 3.5+104-ace829667x265 : build info [GCC 13.1.0][64 bit] 8bit+10bit+12bitx265 : using cpu capabilities: MMX2 SSE2Fast LZCNT SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2x265 : Main profile, Level-3.1 (Main tier)x265 : Thread pool created using 16 threadsx265 : Slices : 1x265 : frame threads / pool features : 4 / wpp(12 rows)x265 : Coding QT: max CU size, min CU size : 64 / 8x265 : Residual QT: max TU size, max depth : 32 / 4 inter / 4 intrax265 : ME / range / subpel / merge : star / 92 / 5 / 5x265 : Keyframe min / max / scenecut / bias : 10 / 250 / 40 / 5.00x265 : Lookahead / bframes / badapt : 60 / 8 / 2x265 : b-pyramid / weightp / weightb : 1 / 1 / 1x265 : References / ref-limit cu / depth : 5 / off / offx265 : AQ: mode / str / qg-size / cu-tree : 2 / 1.0 / 32 / 1x265 : Rate Control / qCompress : CRF-45.0 / 0.60x265 : tools: rect amp rd=6 psy-rd=2.00 rdoq=2 psy-rdoq=1.00 tskipx265 : tools: signhide tmvp b-intra strong-intra-smoothing deblock saox265 : frame I: 2, Avg QP:43.03 kb/s: 334.20x265 : frame P: 37, Avg QP:46.40 kb/s: 18.43x265 : frame B: 61, Avg QP:48.61 kb/s: 12.51x265 : Weighted P-Frames: Y:0.0% UV:0.0%x265 : Weighted B-Frames: Y:0.0% UV:0.0%encoded 100 frames in 14.55s (6.87 fps), 21.14 kb/s, Avg QP:47.68I'm looking into av1 encoder now, will edit or post another commentlaterok avi1 encoder svt-av1 fromhttps://jeremylee.sh/bins/actually 2x faster than hevc on my 5800x and does better quality at same size, at qp 60 (lowest is 63) ... got it to around 560 KB and seems better quality than hevcSee attached file ... command line to encode is below, first line--qp is quality factor - -q, --qp Initial QP level value, default is 35 [1-63]--preset is like the encoding complexity in x264/hevc (that veryfast, slow, placebo etc) - 0 is highest (like placebo), goes up to 13 for lowest qualityCode:SvtAv1EncApp.exe --input test.yuv --width 1280 --height 720 --fps 10 --color-format 1 --profile 0 --preset 0 --qp 60 --output test_qp60_av1_full.mkvSvt: -------------------------------------------Svt: SVT : SVT-AV1 Encoder Lib v1.6.0Svt: SVT  : GCC 13.1.0 64 bitSvt: LIB Build date: Jul 5 2023 08:02:30Svt: -------------------------------------------Svt: Number of logical cores available: 16Svt: Number of PPCS 141Svt: [asm level on system : up to avx2]Svt: [asm level selected : up to avx2]Svt: -------------------------------------------Svt: SVT : main profile tier (auto) level (auto)Svt: SVT : width / height / fps numerator / fps denominator : 1280 / 720 / 10 / 1Svt: SVT : bit-depth / color format : 8 / YUV420Svt: SVT : preset / tune / pred struct : 0 / PSNR / random accessSvt: SVT : gop size / mini-gop size / key-frame type : 161 / 32 / key frameSvt: SVT : BRC mode / rate factor : CRF / 60Svt: -------------------------------------------Encoding 2000Average System Encoding Speed: 10.793146SUMMARY --------------------------------- Channel 1 --------------------------------Total Frames Frame Rate Byte Count Bitrate3146 10.00 fps 570930 14.52 kbpsChannel 1Average Speed: 11.181 fpsTotal Encoding Time: 281370 msTotal Execution Time: 281856 msAverage Latency: 12762 msMax Latency: 15105 ms

author: BrianHG
author_rank: Super Contributor
timestamp: October 09, 2023, 09:31:42 pm
content: Hi mariush,Thanks for the efforts. I noticed you used 10fps. Yup, even in h264, seen in my linked video examples, my 10fps .mp4 file size ~matched your .h265.Except for 1, none of my PCs / phones are even new or fast enough to play your AV1 files.But damn, that 'test_qp60_av1_full.mkv' looks perfect at 600kb. (Used a newer VLC software player)But it wouldn't seek.Anyways, I will be demoing on a bunch of 4 year old 25$ Samsung Android phones, so for now, the .h264 will offer the least headaches. I just need to delete a ton of junk, or add a micro SD card and live with 4x the video file size.

author: mariush
author_rank: Super Contributor
timestamp: October 09, 2023, 09:49:31 pm
content: On Windows, try Media Player Classic - Home Cinema, not from the mpc-hc website, from github :https://github.com/clsid2/mpc-hc/releasesthe official website is not updated anymore.The AV1 video plays with around 4% cpu usage on an old laptop with i5-3210m and 4 GB DDR3 and integrated graphics.AV1 is understandable if it's not on smartphones/tablets as it's relatively new.You may want to try VP9 as well... the tablet/phones chips may have vp9 decoders because google released the hardware decoder (as in circuitry to put in chip) free of charge to companies if my memory is correct. But.. I don't know if the quality will be better than h264, I don't think it's optimized for such images (with sharp edges)ps... it's AV1 , VC1 is an older codec from microsoft, a bit worse than h264 in quality.

author: BrianHG
author_rank: Super Contributor
timestamp: October 09, 2023, 10:12:23 pm
content: LOL, just did an audio sync test. All my PC seem to play my stopwatch tone ~50ms early while with the same file, both of my Android smartphone players play the tone around ~50ms late.The error is within normal human corrective perception, so I wont bother trying to improve things.(I guess I'm not a normal human as I can tell. Always been super-sensitive sensitive to AV sync as well as frame rate...)

author: amyk
author_rank: Super Contributor
timestamp: October 09, 2023, 10:17:25 pm
content: Quote from: BrianHG on October 06, 2023, 12:41:15 amIt seems others have already provided solutions, but that begs the question of what computers you're using; I could do screen captures (XGA, 15fps) perfectly well, 20 years ago, on not-fast hardware for that time.

author: BrianHG
author_rank: Super Contributor
timestamp: October 09, 2023, 10:43:05 pm
content: Amd Phenom II X4 955, 3.21GHz, 8GB.Is my fastest system.Capturing 15fps, it can do. I need perfect time with reference to the animation, no frame skips.And it can just barely realtime compress while running another software to synthesize my clock display for capture.My video card has no encoding or decoding capabilities, it would be a 100% software capture from system display which is not the same as capturing from a video input port.My frame counter is also a clock reference for the player on the other side and the video sync VS an authentic set FPS will make the tenth's seconds playback jump and stutter as a frame loss or insertion is made for correcting clock cycles VS video rendering speed of my timer.Rendering frames and using VirtualDub to injest frames by number seems the best way to go.

author: BrianHG
author_rank: Super Contributor
timestamp: October 10, 2023, 01:12:32 am
content: LOL, again about the lipsync...All configurations, 44.1k or 48k, cbr, vbr, .mp3, .wav on the PC, the audio comes out ahead 1 frame.On Android, using VLC, all 44.1k audio playback comes out late by 2 frames. Using 48k vbr .mp3, the sound comes out on time.Android's stock video player, only cbr 44.1k .mp3 has the audio delayed by 2 frames. All other audio formats, even 44.1k vbr .mp3 has the audio coming out on time.Remember, at 20fps, 2 frames = 0.1 second delay.I think no one has certified tested 44.1k audio in a video stream. 48k seems to be the industry standard.

author: mariush
author_rank: Super Contributor
timestamp: October 10, 2023, 07:25:45 am
content: Containers allow you to specify positive or negative audio delay when mixing, I know for sure MKV container supports it. MP4 should as well.The encoders add some samples or the decoder adds a delay, mp3 has 1156 samples added at the start .. seehttp://forum.doom9.org/archive/index.php/t-164363.htmlTry command line opus encoder (it's better than aac or mp3) or flac (lossless audio)You should be able to use Mkvtoolnix or mp4box (or some other mp4 muxer) and specify the delay if needed.