-use_wallclock_as_timestamps adds delay in live stream - ffmpeg

We have a livestream (MPEG-TS with RTP), which we currently, for testing purposes, replay with tcpreplay.
Our mpeg-ts stream consists of 4 streams (codec details omitted for brevity).
Stream #0:2: Video: h264
Stream #0:1: Audio: mp2
Stream #0:4: Data: bin_data ([6][0][0][0] / 0x0006)
Strean #0:3: Data: bin_data (FBID / 0x4494246)
Stream #0:0: Data: klv (KLVA / 0x41564C4B)
Sometimes the stream indexes are different (like audio stream being stream 0 and so on, I don't know if thats normal behavior)
What we currently try is just to get the stream and copy it with ffmpeg, like
ffmpeg -nostdin -hide_banner -i rtp://239.0.0.2:3000 -map 0 -codec copy -f rtp_mpegts rtp://239.0.0.1:2000`
This leads to the error Application provided invalid, non monotonically incereasing dts to muxer in stream 0: [NUMBER] >= 0
It always says stream 0 no matter what stream 0 contains.
if I add use_wallclock_as_timestamps it works but adds a delay (compared to a video directly streamed from 239.0.0.2:3000 of ~10seconds which are never caught up.
If I set the output format to mpegts instead of rpt_mpegts it works as expected, the same I if don't map the KLVA and FBID stream.
Is this behavior expected (because of wallclock) or what can I do to either use_wallclock_as_timestamps without delay or get rid of the error above?

Related

How do I get audio files of a specific file size?

Is there any way to use ffmpeg to accurately break audio files into smaller files of a specific file size, or pull a specific number of samples from a file?
I'm working with a speech-to-text API that needs audio chunks in exactly 160,000 bytes, or 80,000 16-bit samples.
I have a video stream, and I have an ffmpeg command to extract audio from it:
ffmpeg -i "rtmp://MyFMSWorkspace/ingest/test/mp4:test_1000 live=1" -ar 16000 -f segment -segment_time 10 out%04d.wav
So now I have ~10 second audio chunks with a sample rate of 16 kHz. Is there any way to break this into exactly 160kb, 5 second files using ffmpeg?
I tried this:
ffmpeg -t 00:00:05.00 -i out0000.wav outCropped.wav
But the output was this:
Input #0, wav, from 'out0000.wav':
Metadata:
encoder : Lavf56.40.101
Duration: 00:00:10.00, bitrate: 256 kb/s
Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 16000 Hz, 1 channels, s16, 256 kb/s
Output #0, wav, to 'outCropped.wav':
Metadata:
ISFT : Lavf56.40.101
Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 16000 Hz, mono, s16, 256 kb/s
Metadata:
encoder : Lavc56.60.100 pcm_s16le
Stream mapping:
Stream #0:0 -> #0:0 (pcm_s16le (native) -> pcm_s16le (native))
Press [q] to stop, [?] for help
size= 156kB time=00:00:05.00 bitrate= 256.1kbits/s
but now the size is 156kb
EDIT:
My finished command is:
ffmpeg -i "url" -map 0:1 -af aresample=16000,asetnsamples=16000 -f segment -segment_time 5 -segment_format sw out%04d.sw
That output looks perfectly right. That ffmpeg size is expressed in KiB although it says kB. 160000 bytes = 156.25 kB + some header data. ffmpeg shows size with fractional part hidden. If you want a raw file, with no headers, output to .raw instead of .wav.
For people converting video files to MP3s split into 30 minute segments:
ffmpeg -i "something.MP4" -q:a 0 -map a -f segment -segment_time 1800 FileNumber%04d.mp3
The -q option can only be used with libmp3lame and corresponds to the LAME -V option (source)

FFMPEG attach file as metadata

I have a set of images which I want to convert to a video using ffmpeg. The following command works perfectly fine:
ffmpeg -y -i frames/%06d.png -c:v huffyuv -pix_fmt rgb24 testout.mkv
I have some meta data in a binary file which I want to attach with the video. I tried doing the following, but it gives me an error:
ffmpeg -y -i frames/%06d.png -c:v huffyuv -pix_fmt rgb24 -attach mybinaryfile -metadata:s:2 mimetype=application/octet-stream testout.mkv
This is the error:
[matroska # 0x656460] Codec for stream 1 does not use global headers but container format requires global headers
[matroska # 0x656460] Attachment stream 1 has no mimetype tag and it cannot be deduced from the codec id.
Output #0, matroska, to 'testout.mkv':
Metadata:
encoder : Lavf56.33.101
Stream #0:0: Video: huffyuv (HFYU / 0x55594648), rgb24, 640x640, q=2-31, 200 kb/s, 25 fps, 1k tbn, 25 tbc
Metadata:
encoder : Lavc56.39.100 huffyuv
Stream #0:1: Attachment: none
Metadata:
filename : 2ceb-1916-56bb-3e10
Stream mapping:
Stream #0:0 -> #0:0 (png (native) -> huffyuv (native))
File 2ceb-1916-56bb-3e10 -> Stream #0:1
Could not write header for output file #0 (incorrect codec parameters ?): Invalid argument
It would be wonderful if somebody can explain to me what am I doing wrong :)
You need to specify your stream properly
Example:
ffmpeg -y -i frames/%06d.png -c:v huffyuv -pix_fmt rgb24 -attach mybinaryfile \
-metadata:s:t mimetype=application/octet-stream testout.mkv
This command will set the metadata for all attachment (t) streams (s). If you have more than one attachment, and the metadata are different, then you will have to be more specific, such as:
-metadata:s:t:0 mimetype=text/plain \
-metadata:s:t:1 mimetype=application/gzip
This will set the metadata for the first attachment as mimetype=text/plain, and the second as mimetype=application/gzip. Remember that the stream index starts at 0, so the first steam is labeled 0.
What was wrong with your command
Using -metadata:s:2 (which appears to have been copied verbatim from the documentation) sets the metadata for the third stream, regardless of stream type (because no specifier is present), but your output only contained two streams.
Attachment: None
You may see something like this:
Output #0, matroska, to 'output.mkv':
...
Stream #0:1: Attachment: none
Metadata:
filename : 2ceb-1916-56bb-3e10
mimetype : application/octet-stream
Attachment: none does not mean that there is no attachment, but that there is no format associated with it, so it can be ignored.
Also see
Stream specifiers and the ffmpeg documentation on -attach, -metadata, and -map_metadata for more details.

Extract audio from Audio wrapped into video stream ffmpeg/ffmbc

I have a mov file :
Metadata:
timecode: 09:59:50:00
Duration: 00:00:30.00, bitrate: 117714 kb/s
Stream #0.0(eng): Video: dvvideo, yuv422p, 1440x1080i tff [PAR 4:3 DAR 16:9]
, 115200 kb/s, 25.00 fps
Metadata:
codec_name: DVCPRO HD 1080i50
Stream #0.1(eng): Audio: pcm_s16le, 48000 Hz, 2 channels, s16, 1536 kb/s
Stream #0.2(eng): Data: unknown (tmcd)
I can see from MediaInfo
That the Audio is Muxed into the video. I'm trying to re-wrap this into an XDCAM, and copy over the audio streams. The problem is that I don't know how to map the audio that is wrapped into the video?
This is the command I have so far:
ffmbc -threads 8 -i "input.mov" -threads 8 -tff
-pix_fmt yuv422p -vcodec mpeg2video -timecode 09:59:50:00
.. other tags omitted ..
-acodec pcm_s24le
-map_audio_channel 0.1:0-0.1:0
-map_audio_channel 0.1:1-0.1:1
-f mov -y "output.mov"
-acodec pcm_s24le
-map_audio_channel 0.2:0-0.2:0
-map_audio_channel 0.2:1-0.2:1 -newaudio
When executed this returns "Cannot find audio channel 0.2.0". I changed the input stream identifier to stream 0, and 1 for the audios. Which when executed returned "Cannot find audio channel #0.0.0" presumably because it's trying to find a audio channel within the video stream?
How can I extract the audio from this file?
You may notice I'm using FFMBC, not FFMPEG ( there is no tag for FFMBC ), but I imagine it's the same for both. I'm not constrained to FFMBC, I can move to FFMPEG if it has a solution.
Thanks

Error while opening encoder for output stream #0.0 - maybe incorrect parameters such as bit_rate, rate, width or height

I am using this command to convert an avi,mov,m4v video files to flv format via FFMPEG
/usr/local/bin/ffmpeg -i '/home/public_html/files/video_1355440448.m4v' -s '640x360' -sameq -ab '64k' -ar '44100' -f 'flv' -y /home/public_html/files/video_1355440448.flv
[flv # 0x68b1a80] requested bitrate is too low
Output #0, flv, to '/home/files/1355472099-50cadce349290.flv':
Stream #0.0: Video: flv, yuv420p, 640x360, q=2-31, pass 2, 200 kb/s, 90k tbn, 25 tbc
Stream #0.1: Audio: adpcm_swf, 44100 Hz, 2 channels, s16, 64 kb/s
Stream mapping:
Stream #0.0 -> #0.0
Stream #0.1 -> #0.1
Error while opening encoder for output stream #0.0 - maybe incorrect parameters such as bit_rate, rate, width or height
-------------------------------
RESULT
-------------------------------
Execute error. Output for file "/home/public_html/files/video_1355472099.avi" was found, but the file contained no data. Please check the available codecs compiled with FFmpeg can support this type of conversion. You can check the encode decode availability by inspecting the output array from PHPVideoToolkit::getFFmpegInfo().
But if I manually used this command then its working
/usr/local/bin/ffmpeg -i '/home/public_html/files/video_1355440448.m4v' -s '640x360' -sameq -ab '64k' -ar '44100' -f 'flv' -y /home/public_html/files/video_1355440448.flv
This is because you have two streams and output will be encoding then resizing, see your output messages:
Stream #0.0 -> #0.0
Stream #0.1 -> #0.1
... you use adpcm_swf audio and yuv420p video
The answer is very simple, you need to put copy as your audio codec ...
See my example with video mpeg4,yuv420p and audio ac3 ...
ffmpeg -i input.mkv -vf scale=720:-1 -acodec copy -threads 12 output.mkv
this will change first size = 720 with aspect ratio = -1 (unknown). Also you need to use:
-acodec copy -threads 12
If don't use this you will have one error.
For example: When I used it, the output encoding messages show me this and it works well:
[h624 # 0x874e4a0] missing picture in access unit93 bitrate=1034.4kbits/s
Last message repeated 1163 times5974kB time=53.47 bitrate= 915.3kbits/s
You need to use for flv format file, something like this:
ffmpeg -i input.mp4 -c:v libx264 -crf 19 output.flv
You are given an error message
[flv # 0x68b1a80] requested bitrate is too low
You need to change bitrate to a valid. It is better if you use a different codec
-acodec libmp3lame
And remove the option -sameq. This option does NOT mean 'same quality'. Actually means 'same quantizers'!
I had a similar problem due to size constraints. The original image size was strange (width=1343), meaning that when I tried to specify a new size with -s, any rounding error caused problems. Make sure that the new image size can have the exact same aspect ratio!
I have got the same issue
- requested bitrate is too low
and just resolved this issue by lowering down the bit rate
by adding -b:a 32k

FFMPEG - errors when combining videos

I have two .OGG files of similar size, FPS and duration. My goal is to combine them into a side-by-side presentation using FFMPEG. To this end I've tried the following cmd:
ffmpeg -i subject.ogg -vf "[in]pad=3*iw:3*ih[left];movie=clinician.ogg[right];[left] [right]overlay=100:0[out]" combined.ogg
Suffice to say that the resultant video is non-playable. During the combination process FFMPEG prints lots of errors that read like:
[Parsed_overlay_2 # 0x1eb7d3e0] Buffer queue overflow, dropping
What is this telling me?
Note:
both source files are playable
I padded the 'output' to be rather large in an attempt to understand the params
the placement of the 2nd video at 100:0 is arbitrary. Once I get the cmd working I'll move it to a better location in the output.
both videos began life as .FLV recorded from web cameras. I converted them to .ogg as FFMPEG didn't want to combine two .FLV files. If there is a better route to this, please let me know.
So - what's wrong with my parameters and what am I doing to cause these FFMPEG errors?
EDIT:
ffmpeg -i clinician.ogg
Input #0, ogg, from 'clinician.ogg':
Duration: 00:05:20.98, start: 0.001000, bitrate: 2273 kb/s
Stream #0:0: Video: theora, yuv420p, 500x500 [SAR 1:1 DAR 1:1], 1k tbr, 1k tbn, 1k tbc
Metadata:
SERVER : Red5 Server 1.0.0 RC1 $Rev: 4193 $
CANSEEKTOEND : true
ENCODER : Lavf54.31.100
Stream #0:1: Audio: vorbis, 8000 Hz, stereo, s16
Metadata:
SERVER : Red5 Server 1.0.0 RC1 $Rev: 4193 $
CANSEEKTOEND : true
ENCODER : Lavf54.31.100
ffmpeg -i subject.ogg
Input #0, ogg, from 'subject.ogg':
Duration: 00:05:17.60, start: 0.001000, bitrate: 1341 kb/s
Stream #0:0: Video: theora, yuv420p, 300x300 [SAR 1:1 DAR 1:1], 83.33 tbr, 1k tbn, 1k tbc
Metadata:
SERVER : Red5 Server 1.0.0 RC1 $Rev: 4193 $
CANSEEKTOEND : true
ENCODER : Lavf54.31.100
Stream #0:1: Audio: vorbis, 8000 Hz, stereo, s16
Metadata:
SERVER : Red5 Server 1.0.0 RC1 $Rev: 4193 $
CANSEEKTOEND : true
ENCODER : Lavf54.31.100
Converting to x264 was a great suggestion. That seemed to turn the tide.
Here are some notes for posterity:
to convert flv to x264 and correct audio sync issues:
ffmpeg -y -i subject_s_2242_r_1658.flv -async 1 -ac 2 -strict -2 -acodec vorbis \
-c:v libx264 -preset slow -crf 22 subject.mkv
to merge two x264 files into a single side-by-side file and put the two mono audio tracks into stereo in the resultant file:
ffmpeg -y -i clinician.mkv -vf: "movie=subject.mkv[right];pad=iw*2:ih:0:0[left];[left][right]overlay=500:0" \
-filter_complex "amovie=clinician.mkv[l];amovie=subject.mkv[r];[l][r] amerge" final.mkv
I was unable to install AVISYNTH (running on CentOS 6.2) but it does look like a great solution.
It is probably easiest to do this using Avisynth.
Make the following input.avs file:
a = AviSource("first.avi")
b = AviSource("second.avi")
StackHorizontal(a,b)
Then run ffmpeg -i input.avs output.avi ... plus any other options you want.
EDIT: Another way to do it (not fast) is to dump the frames from both files to png and combine them with ImageMagick (for example montage) or similar image processing tools.
#!/bin/bash
ffmpeg -i first.avi first_%05d.png
ffmpeg -i second.avi second_%05d.png
for file in first_*.png ; do montage ${file} ${file/first/second} ${file/first/output} ; done
ffmpeg -i output_%05d.png output.avi
This actually lets you do a lot more image processing than just side-by-side, you can do arbitrary scale/overlay/background/etc. The problem is that the N-th frame from one file may not be at exactly the same time as the N-th frame from the other file, if they are variable frame rate, this is something that AviSynth handles perfectly for you. If the clips are constant frame rate that is not a problem.
Combining clips by making a new clip containing both like this (whether through avisynth or not) requires recompressing the video, and reduces video quality/increases file size.
I am not sure how to read ogg files into Avisynth, but there is probably a way. Check the FAQ on input formats.
Side comment: The choice of theora/ogg is strange. Better: H.264 in mp4 container.

Resources