Friday, September 21, 2018

Raspberry Pi Video With Accurate Frame Timestamps

The `raspivid` tool grabs raw H.264 compressed video. Unfortunately, this stream is lacking frame timestamps. If you're just grabbing the default 25 frames per second and the system never stutters and always grabs frames at exactly that rate, it's fine. I was playing around with grabbing at 10 fps for a lower bitrate stream and that was confusing all the tools. ffmpeg considers a raw H.264 stream without timestamps to be a bug and the warning messages suggests that they won't support importing it in the future.

raspivid does have a way of capturing frame timestamps to a separate text file, and mkvmerge can reintegrate that into a video file. From there, ffmpeg can convert that '.mkv' file to the more popular '.mp4' file format.


sudo apt-get install -y mkvtoolnix ffmpeg

echo "# timestamp format v2" > vidf.264.pts
raspivid -o vidf.264 -t 10000 -pts -n -fps 10 >> vidf.264.pts
mkvmerge -o /tmp/b.mkv --timestamps 0:vidf.264.pts vidf.264
ffmpeg -i /tmp/b.mkv -c copy /tmp/f.mp4


mkvmerge needs a header line on the frame timestamp file, so we create the file with just that header, then append the data to it. The raspivid command captures 10 seconds (10000 milliseconds) at 10 frames per second with no on screen preview. It captures the video to the named file vidf.264 and writes the frame timestamps to standard out which is appended to vidf.264.pts . mkvmerge then does the reintegration of the timestamps with the video stream. Lastly, ffmpeg converts the mkv file (which works directly with VLC and other viewers) to mp4 which works with just about everything.