FFMPEG attach file as metadata - ffmpeg

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.

Related

Does Webm support cover art?

I am converting MP3 to Webm and the MP3 file includes a video stream for the cover art.
ffprobe filename.mp3
...
Stream #0:0: Audio: mp3, 22050 Hz, stereo, fltp, 64 kb/s
Stream #0:1: Video: mjpeg (Baseline), yuvj444p(pc, bt470bg/unknown/unknown), 300x300, 90k tbr, 90k tbn, 90k tbc (attached pic)
Using ffmpeg with libopus codec to convert the file causes a VP9 video stream that doesn't work well. I noticed:
VLC Player doesn't show the duration and the progress scrubber doesn't move when playing.
Android Media Player doesn't show image for the cover art of the track.
ffprobe filename.webm
...
Input #0, matroska,webm, from 'webm_bad/B01___01_Matthew_____ENGWEBN2DA.webm':
...
Stream #0:0: Video: vp9 (Profile 1), yuv444p(tv, progressive), 300x300, SAR 1:1 DAR 1:1, 1k tbr, 1k tbn, 1k tbc (default)
If I tried to use -vcodec copy option, then I get this error:
[webm # 0x7fdddf028e00] Only VP8 or VP9 or AV1 video and Vorbis or Opus audio and WebVTT subtitles are supported for WebM.
Could not write header for output file #0 (incorrect codec parameters ?): Invalid argument
Error initializing output stream 0:1 --
Does WebM support cover art? If so, how do I transfer the MP3 cover art over using ffmpeg (or other tool)?
No, WebM does not support cover art.
From the FAQ:
The WebM file structure is based on the Matroska media container.
The cover art in a Matroska container is stored in an attachment:
Attachment Elements can be used to store related cover art, [...]
A WebM container does not support attachments:
Attachment
WebM Support
Element Name
Description
Unsupported
Attachments
Contain attached files.
Unsupported
AttachedFile
An attached file.
Unsupported
FileDescription
A human-friendly name for the attached file.
Unsupported
FileName
Filename of the attached file.
Unsupported
FileMimeType
MIME type of the file.
Unsupported
FileData
The data of the file.
Unsupported
FileUID
Unique ID representing the file, as random as possible.
Unsupported
FileReferral
A binary value that a track/codec can refer to when the attachment is needed.
Unsupported
FileUsedStartTime
DivX font extension
Unsupported
FileUsedEndTime
DivX font extension
Maybe you can consider using a different container. Opus audio streams, like the ones in a WebM container, are supported by other containers:
Opus was originally specified for encapsulation in Ogg containers
If you still want to use WebM, an alternative would be to create a video stream with a still image along with an audio stream. The FFmpeg wiki covers that topic in the Slideshow page. Combining that with this answer, which explains how to extract the cover art of an MP3 file, you could do the following:
ffmpeg -i filename.mp3 -an -c:v copy cover.jpeg
ffmpeg -loop 1 -i cover.jpeg -i filename.mp3 -c:v libvpx-vp9 -c:a libopus -b:a 64k -shortest filename.webm
64k is the bitrate that you show in the output of ffprobe.
The encoding might be slow with the second command. The Encode/Youtube page in the FFmpeg wiki shows an example command to create a video with an still image that uses the -framerate 2 option, like this:
ffmpeg -loop 1 -framerate 2 -i cover.jpeg -i filename.mp3 -c:v libvpx-vp9 -c:a libopus -b:a 64k -shortest filename.webm
For some reason I do not know, the output video of that last command cannot be reproduced by my VLC and the player crashes. 6 was the minimum -framerate that did not crash my player, so be careful.

-use_wallclock_as_timestamps adds delay in live stream

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?

Failed to convert webm audio file to mp4 using FFMPEG

I have a webm audio file , I was trying to convert it into mp4 using ffmpeg. But it is failed to create the mp4. The info about the file is as follows.
fmpeg -i 54ebe077-96fc-4ace-9a38-f13c58807322.webm -hide_banner
Input #0, matroska,webm, from '54ebe077-96fc-4ace-9a38-f13c58807322.webm':
Metadata:
encoder : Lavf56.40.101
creation_time : 2019-10-22T11:19:12.000000Z
Duration: 00:00:24.16, start: 0.000000, bitrate: 41 kb/s
Stream #0:0: Video: vp8, yuv420p, 640x480, SAR 1:1 DAR 4:3, 30 fps, 30 tbr, 1k tbn, 1k tbc (default)
Stream #0:1: Audio: opus, 48000 Hz, mono, fltp (default)
At least one output file must be specifiedffmpeg -i 54ebe077-96fc-4ace-9a38-f13c58807322.webm -qscale 0 out.mp4
I was tried to convert it using the following command
ffmpeg -i 54ebe077-96fc-4ace-9a38-f13c58807322.webm -qscale 0 out.mp4
It throws errors
[opus # 0x56489c7f9840] LBRR frames is not implemented. Update your FFmpeg version to the newest one from Git. If the problem still occurs, it means that your file has a feature which has not been implemented.
[opus # 0x56489c7f9840] Error decoding a SILK frame.
[opus # 0x56489c7f9840] Error decoding an Opus frame.
Too many packets buffered for output stream 0:1.
[aac # 0x56489c82d640] Qavg: 59180.625
[aac # 0x56489c82d640] 2 frames left in the queue on closing
Conversion failed!
How to fix this issue? I have played the file in VLC and I can hear the sound from the source file. But failed to convert it
Your ffmpeg is too old
Update your ffmpeg:
Download an already compiled ffmpeg
Or see compile instructions at FFmpeg Wiki
This was ticket #4641: Error decoding SILK frame. The fix is newer than the most current release branch (FFmpeg 4.3 as of writing this), so you have to get a build from the git master branch (either of the links above will do), or wait for FFmpeg 4.4.
If you can't update
If you can't update your ffmpeg the old workaround is to use libopus to decode:
ffmpeg -c:a libopus -i input ...

FFMPEG amerge fails when one audio stream is missing

I am trying to combine two video files (of size 320x240) and create a single, horizontally extended output video file (of size 640x240) but for the audio merging, the command fails when one of the input files does not contain audio stream.
Here's the command I am using:
C:\ffmpeg\bin\ffmpeg.exe -y -i "input1.flv" -i "input2.flv" -filter_complex "nullsrc=size=640x240[base];[0:v]scale=320x240[upperleft];[1:v]scale=320x240[upperright];[base][upperleft]overlay=shortest=1[tmp1];[tmp1][upperright]overlay=shortest=1:x=320:y=0;[0:a][1:a]amerge=inputs=2[aout]" -map [aout] -ac 2 "output.mp4"
This command works fine when both input1.flv and input2.flv contain audio tracks. When either one lacks an audio track, the command gives the following error:
[flv # 0000000004300660] Stream discovered after head already parsed
[flv # 0000000004300660] Could not find codec parameters for stream 1
(Audio: none, 0 channels): unspecified sample format Consider
increasing the value for the 'analyzeduration' and 'probesize' options
Input #1, flv, from 'input2.flv': Metadata:
creationdate : Tue Jan 26 16:50:12 Duration: 00:25:59.10, start: 0.000000, bitrate: 212 kb/s
Stream #1:0: Video: flv1, yuv420p, 320x240, 1k tbr, 1k tbn, 1k tbc
Stream #1:1: Audio: none, 0 channels
Stream #1:2: Data: none [abuffer # 0000000004335620] Value inf for parameter 'time_base' out of range [0 - 2.14748e+009] [abuffer #
0000000004335620] Unable to parse option value "(null)" as sample
format [abuffer # 0000000004335620] Value inf for parameter
'time_base' out of range [0 - 2.14748e+009] [abuffer #
0000000004335620] Error setting option time_base to value 1/0. [graph
0 input from stream 1:1 # 00000000042e4d60] Error applying options to
the filter. Error configuring filters.
Is there a way to make this command work even when one audio stream lacks an audio track or both of the audio streams lack audio tracks?
There's one preparatory command that needs to be executed only once,to generate a file
ffmpeg -f lavfi -t 1 -i anullsrc:r=48000 silence.mkv
For each flv,
ffmpeg -i input1.flv -analyzeduration 10M -i silence.mkv -c copy -map 0 -map 1 input1a.mkv
ffmpeg -i input2.flv -analyzeduration 10M -i silence.mkv -c copy -map 0 -map 1 input2a.mkv
And then,
ffmpeg -i input1a.mkv -i input2a.mkv -filter_complex "[0:v][1:v]hstack=shortest=1[v];[0:a][1:a]amerge[a]" -map [v] -map [a] -ac 2 "output.mp4"

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

Resources