I'm getting started with FFMPEG to add a title video to a few dozen videos I have. What would be the proper command to do this?
Use the concat demuxer
There are several methods to join/merge/concatenate one video to another. This method uses the concat demuxer in ffmpeg to join the title video to the main video. Although there are several steps, it has the advantage that it does not re-encode the video you are adding a title to. So the process is quick and the quality is preserved.
Example
See the attributes of the video you want to add a title video to. In this example it is named main.mp4. When making the title video you will need to ensure that it matches the attributes of the video you want to add a title to.
ffmpeg -i main.mp4
...
Stream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, bt709), 1280x720 [SAR 1:1 DAR 16:9], 988 kb/s, 29.97 fps, 29.97 tbr, 30k tbn, 59.94 tbc (default)
Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 128 kb/s (default)
Generate the title video. Make sure the title video matches the attributes of the main file so it can concatenate properly. This example uses the color and anullsrc source filters to make 5 seconds of black video and silent audio, and the drawtext filter to make text:
ffmpeg -f lavfi -i color=size=1280x720:rate=30000/1001:duration=5:color=black -f lavfi -i anullsrc=sample_rate=44100:channel_layout=stereo -vf "drawtext=text='your title':fontcolor=white:fontsize=48:x=(w-text_w)/2:y=(h-text_h)/2" -c:v libx264 -profile:v main -c:a aac -shortest title.mp4
Make a text file named input.txt. This will be used by the concat demuxer and lists the files that you want to concatenate.
file 'title.mp4'
file 'main.mp4'
Finally, concatenate the title video to the main video with the concat demuxer:
ffmpeg -f concat -i input.txt -c copy output.mp4
Batch mode
ffmpeg does not have a batch mode to automatically do this for a folder of videos. However, it can be done with shell scripting but that is a whole new topic that deserves its own question. See How do you convert an entire directory with ffmpeg? for some examples.
Related
I have a txt file which contains several videos:
file '01.mp4' # No audio, only video
file '02.mp4' # Video with audio
...
All my videos are using same video codecs:
Stream #0:0[0x1](und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 720x1280, 3167 kb/s, 30 fps, 30 tbr, 15360 tbn (default)
And all my video that contains audio are these codecs:
Stream #0:1[0x2](und): Audio: aac (HE-AAC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 43 kb/s (default)
I tried to add silent audio using:
ffmpeg -f lavfi -i anullsrc=channel_layout=stereo:sample_rate=44100 -i 01.mp4 -c:v copy -c:a aac -shortest 01-silentaudio.mp4
But when concatening all my videos, it results in no audio for all videos.
What should I do?
Maybe I can reencode all my video to a specific codec, including my video without sound, in order to have the same codecs for all? What do you think?
Thank you
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.
I am blocked trying to do something, and I'm ready to make a donation if somebody can help me:
I try to concat http://s.serero.free.fr/rolex.mp4 video and http://s.serero.free.fr/video.mp4 video in one output mp4 file and I tried during a big time without results.
I want to concat http://s.serero.free.fr/rolex.mp4 + http://s.serero.free.fr/video.mp4
or http://s.serero.free.fr/video.mp4 + http://s.serero.free.fr/rolex.mp4.
I tried with ffmpeg command line software and with mp4box command line software, I think that I don't have the good method.
I tried to transform http://s.serero.free.fr/video.mp4 in the same format of http://s.serero.free.fr/rolex.mp4 (and vice versa):
I transformed http://s.serero.free.fr/rolex.mp4 with the same frame rate of http://s.serero.free.fr/video.mp4
I transformed http://s.serero.free.fr/rolex.mp4 with the same video bitrate of http://s.serero.free.fr/video.mp4
I transformed http://s.serero.free.fr/rolex.mp4 with the same video audio bitrate of http://s.serero.free.fr/video.mp4
Can somebody help me?
Explain to me what is wrong in my strategy?
Your input parameters vary, so you have to make them similar before concatenation.
rolex.mp4
Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, bt709), 1280x720 [SAR 1:1 DAR 16:9], 835 kb/s, 25 fps, 25 tbr, 90k tbn, 50 tbc (default)
Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 125 kb/s (default)
video.mp4
Video: h264 (High) (avc1 / 0x31637661), yuvj420p(pc), 1152x720, 1749 kb/s, 30 fps, 30 tbr, 15360 tbn, 60 tbc (default)
Audio: mp3 (mp4a / 0x6134706D), 44100 Hz, stereo, s16p, 127 kb/s (default)
This example will make video.mp4 more like rolex.mp4 then concat them:
ffmpeg -i rolex.mp4 -i video.mp4 -filter_complex \
"[1:v]pad=1280:720:(ow-iw)/2:0,fps=25,format=yuv420p[v1]; \
[0:v][0:a][v1][1:a]concat=n=2:v=1:a=1[v][a]" \
-map "[v]" -map "[a]" output.mp4
You don't actually need to declare fps or format because, as the concat filter documentation states:
All corresponding streams must have the same parameters in all
segments; the filtering system will automatically select a common
pixel format for video streams, and a common sample format, sample
rate and channel layout for audio streams, but other settings, such as
resolution, must be converted explicitly by the user.
...but doing so will allow you to manually choose the "common" settings instead of relying on the filter automatically doing so and potentially selecting a setting you don't want.
Thanks for LordNeckbeard for his excellent answer, he just let a little mistake on the command, i just want to a little explanation :
If I want to concat video.mp4(1152X720) with rolex.mp4(1280X720), we must understand that "video.mp4" is the main video so the video(s) to concatene must have exactly the same frame size.
So before to do this operation you need to resize rolex.mp4 video with the same size like video.mp4 with ffmpeg :
ffmpeg -i rolex.mp4 -s 1152x720 -c:a copy newrolexsized.mp4
No video.mp4 and newrolexsized.mp4 has the same frame size, and you can use the command (spcifying pad=1152:720 => size of the main video):
ffmpeg -i video.mp4 -i newrolexsized.mp4 -filter_complex "[1:v]pad=1152:720:(ow-iw)/2:0,fps=25,format=yuv420p[v1];[0:v][0:a][v1][1:a]concat=n=2:v=1:a=1[v][a]" -map "[v]" -map "[a]" out.mp4
I have a .wtv file, recorded from Windows Media Center, that I'd like to extract the subtitles from. The video is encrypted, but the subtitles are not (something I've been able to verify by using CCExtractor with it). FFMpeg lists the video as such:
Duration: 00:07:01.72, start: 2.214551, bitrate: 9154 kb/s
Stream #0:0[0xcc](eng): Audio: ac3, 48000 Hz, 5.1(side), fltp, 384 kb/s
Stream #0:1[0xcd]: Video: mpeg2video (Main), yuv420p(tv), 1920x1080 [SAR 1:1 DAR 16:9], Closed Captions, max. 25000 kb/s, 29.97 fps, 29.97 tbr, 10000k tbn, 59.94 tbc
Stream #0:2[0xce]: Subtitle: eia_608
When I try to run
ffmpeg -i myvideofile.wtv -an -vn -map 0:2 -c:s:0 srt test.srt
I see a lot of the following errors:
[wtv # 0x7fef79806e00] encrypted stream detected (st:1), decoding will likely fail
Last message repeated 8 times
[Closed caption Decoder # 0x7fef7982cc00] Data Ignored since exceeding screen width
and eventually:
Output file is empty, nothing was encoded (check -ss / -t / -frames parameters if used)
I don't mind it being able to decode the video stream, but is that causing the closed caption error? If it can't decode the video it doesn't know the screen width, perhaps? Is it possible to set the closed caption decoder to ignore such errors and output anyway (it's just in text format after all)?
I have checked the FFMpeg documentation and many forums and figured out the correct command-line to extract subtitles from an .MP4 video should look like so:
ffmpeg -i video.mp4 -vn -an -codec:s:0 srt out.srt
However, I get the following error, which lends me to question whether this is feasible at all:
Error while opening encoder for output stream #0:0 - maybe incorrect parameters
such as bit_rate, rate, width or height
Using ffmpeg -codecs, I can confirm that ffmpeg should be able to encode subrip subtitles.
Using ffmpeg -i video.mp4, I can see that there is two subtitle tracks embedded in the video :
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'video.mp4':
...
Stream #0:0(und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p, 720x572 [SAR 64:45 DAR 256:143], 1341 kb/s, 25 fps, 25 tbr, 90k tbn, 180k tbc
Stream #0:1(eng): Audio: aac (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 191 kb/s
Stream #0:2(fra): Audio: aac (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 191 kb/s
Stream #0:3(eng): Subtitle: dvd_subtitle (mp4s / 0x7334706D)
Stream #0:4(und): Subtitle: mov_text (text / 0x74786574)
EDIT
I have tested with the simplified command-line shown in the comments but I still get the same error. Here is a link to the detailed verbose output from running the command. I have also tried to completely disable metadata and chapters in the resulting output but that still produces the same error.
I enventually figured out why I did not succeed:
The specified command-line would have been perfectly fine if the subtitles from the source video were encoded in a text-based representation. However, as can be seen in the output to the ffmpeg -i command-line, the subtitles are encoded in the "dvd_subtitle" format.
The dvd_subtitle format stores bitmaps for each subtitle in the video. Therefore, there is no way ffmpeg would be able to translate the bitmaps into text.
For this task, one has to resort to an OCR-based software which assists a user with the task of identifying each subtitle as text from its bitmap représentation.
(There is a secondary text-based subtitle in the source video, but I don't know where it came from and is not seen by most popular players. For all intents and purposes, this "mov_text" subtitle seems to be a stub placeholder, probably an artifact of the conversion from the original DVD)
Just FYI, (Can't comment due to rep yet), but extracting SRT from an MP4 will result in a file formatted as MOV_Text not the regular SRT. It will still get added and work but its like changing mp4 to m4v. While it usually works, things don't work the same in the code. Mov_text is horrible for manually adjusting font/size etc etc. Best bet is to download and test an SRT from the web!
This will work, but will result in mov_text coded srt file:
ffmpeg -i in.mp4 out.srt
Try using map option...
if there are too many streams in input files....
Syntax would be:
ffmpeg -i video.mp4 -map 0:4 out.srt
Since there are two subtitle streams in your video, first on 0:3 which is dvdsubtitle so cannot be converted to srt so we will convert second subtitle on 0:4 stream which is mov_text and is soft copy of subtitle so can be easily converted....