Hardcoding subtitles from DVD or VOB file with ffmpeg - ffmpeg

I have some DVDs that I would like to encode so that I can play them on a Chromecast, with subtitles. It seems that Chromecast only supports text-based subtitle formats, while DVD subtitles are in a bitmap format, so I need to hardcode the subtitles onto the video stream.
First I use vobcopy to create a VOB file:
vobcopy -I /dev/sr0
Next I want to use ffmpeg to encode it as a video stream in a format that is supported by the Chromecast. This is the closest I've come so far (based on the ffmpeg documentation):
ffmpeg -analyzeduration 100M -probesize 100M -i in.vob \
-filter_complex "[0:v:0][0:s:0]overlay[vid]" -map "[vid]" \
-map 0:3 -codec:v libx264 -crf 20 -codec:a copy out.mkv
The -filter_complex "[0:v:0] [0:s:0]overlay[vid] parameters should overlay the first subtitle stream on the first video stream (-map 0:3 is for the audio). This partially works, but the subtitles are only shown for a fraction of a second (I'm guessing one frame).
How can I make the subtitles display for the correct duration?
I'm using ffmpeg 4.4.1 on Linux, but I've also tried the latest snapshot version, and tried gstreamer and vlc (but didn't get far).

The only solution I found that worked perfectly was a tedious multi-stage process.
Copy the DVD with vobcopy
vobcopy -I /dev/sr0
Extract the subtitles in vobsub format using mencoder. This command will write subs.idx and subs.sub. The idx file can be edited if necessary to tweak the appearance of the subtitles.
mencoder *.vob -nosound -ovc frameno -o /dev/null \
-vobsuboutindex 0 -sid 0 -vobsubout subs
Copy the audio and video from the VOB into an mkv file. ffprobe can be used to identify the relevant video and audio stream numbers.
ffmpeg -fflags genpts -i *vob -map 0:1 -map 0:3 \
-codec:v copy -codec:a copy copied_av.mkv
Merge the subtitles with the audio/video stream.
mkvmerge -o merged.mkv copied_av.mkv subs.sub subs.idx
Then ffmpeg will work reliably with the mkv file to write hardcoded subtitles to the video stream.
ffmpeg -i merged.mkv -filter_complex "[0:v:0][0:s:0]overlay[vid]" \
-map [vid] -map 0:1 -codec:v libx264 -codec:a copy hardcoded.mkv

Related

FFMPEG: How to convert M2V Video with two single WAV tracks (stereo) to MP4?

How can I create a MP4 file with ffmpeg out of a M2V-Video-File and two WAV-Files (one file for the right audio channel and one for the left audio channel)?
try this:
ffmpeg -i video.m2v -i audio1.wav -i audio2.wav -c:v copy -c:a aac -map 0:v:0 -filter_complex "[1:a][2:a]join=inputs=2:channel_layout=stereo[a]" -map "[a]" output.mp4
I believe mp4 files cannot contain PCM audio, hence converting to aac.

Converting a large number of MP3 files to videos for YouTube, each using same the JPEG image

I am looking for a way to convert large number of MP3 files to videos, each using the same image. Efficient processing time is important.
I tried the following:
ffmpeg -i image.jpg -i audio.mp3 -vcodec libx264 video.mp4
VLC media player played the resulting video file with the correct sound, but a blank screen.
Microsoft Media Player played the sound and showed the intended image. I uploaded the video to YouTube and received the message:
"The video has failed to process. Please make sure you are uploading a supported file type."
How can I make this work?
Create video:
ffmpeg -framerate 6 -loop 1 -i input.jpg -c:v libx264 -vf format=yuv420p -t 00:10:00 video.mp4
The duration (-t) should be ≥ the MP3 with the longest duration.
Now stream copy the same video for each MP3:
ffmpeg -i video.mp4 -i audio.mp3 -map 0:v -map 1:a -c copy -movflags +faststart -shortest output.mp4
Some notes regarding compatibility:
MP3 in MP4 does not have universal support, but will be fine in YouTube. If your target players do not like it then add -c:a aac after -c copy to output AAC audio.
If your target player does not like it then increase the -framerate value or add the -r output option with an appropriate value, such as -r 15. Again, YouTube should be able to handle it.

How to add a Subtitle as default to a video already containing a subtitle stream using ffmpeg? [duplicate]

By adding an .ass subtitles track to an mkv video with ffmpeg, it isn't set as default track, so on playback you have to manually turn on subtitles. Is it possible to set the default flag for the subtitles track?
ffmpeg command used:
ffmpeg -i video.mp4 -i subtitles.ass -c:v libx264 -preset veryslow \
-pix_fmt yuv420p10le -c:a copy -c:s copy output.mkv
Note that I want to keep .ass subtitle format, not convert the subtitles to mov_text like suggested in this similar question:
How to set default streams with ffmpeg
There is the possibility to set the default flag afterwards with mkvpropedit like this:
mkvpropedit output.mkv --edit track:s1 --set flag-default=1
But is it possible to do this directly with ffmpeg?
I think as per this patch this is now possible. At least for me it works with:
ffmpeg -i in.mp4 -i in.srt -c copy -disposition:s:0 default out.mkv
Note s in -disposition:s:0 in this case stands for subtitle and not stream. To select the second steam by index use -disposition:1.
You can use 'forced' instead of default to force vlc to play it
ffmpeg -f mp4 -i outfile.mp4 -f srt -i VTS_07_0.EnglishV2.srt -c:v copy -c:a copy -metadata:s:a:0 language=Japanese -c:s mov_text -metadata:s:s:0 language=English -disposition:s:s:0 forced mix.mp4

Use ffmpeg to add multiple subtitles separately to a video

I am trying to add multiple languages of subtitles to a video using ffmpeg. I succeeded in adding 1 language, but can't seem to add a second one.
I use this simple script to add english subtitles to my video.
ffmpeg -i %1 -i subs_eng.srt -map 0 -vcodec copy -acodec copy -scodec subrip -metadata:s:s:0 language=English "%~n1"_eng.mkv
In addition, I run another script to add the Dutch subtitles.
ffmpeg -i %1 -i subs_nl.srt -map 0? -vcodec copy -acodec copy -scodec subrip -metadata:s:s:1 language=Dutch "%~n1"_nl.mkv
But whenever I add the second language, it doesn't seem to do anything. The command terminal shows that ffmpeg is processing the video, but there is only 1 subtitle language available in vlc media player (the first one).
I really want to be able to add it in 2 takes rather than in the same script, as I don't have both languages for all of my video's.
Without -map for the subtitle stream, ffmpeg will select only one subtitle stream from among all inputs.
ffmpeg -i %1 -i subs_nl.srt -map 0 -map 1 -vcodec copy -acodec copy -c:s:0 copy -c:s:1 subrip -metadata:s:s:1 language=Dutch "%~n1"_nl.mkv
I set codec mode for the existing subtitle stream to copy and subrip for only the new one. This assumes you muxed exactly one subtitle stream earlier.
It is easier in fact. You can add subtitles to a file without removing old ones by
ffmpeg -i input.mkv -i input.srt -map 0 -map 1 -c copy output.mkv
-map x selects all streams from a file so all streams from both files get into the output file. If you add more input subtitle tracks, you need to supply -map 2, -map 3 and so on. See the very conscious and simple Map documentation.
Now more tricky is if you want to properly label these subtitles. You can add
-metadata:s:s:0 language=heb -metadata:s:s:0 handler_name=Hebrew -metadata:s:s:0 title=Hebrew
-metadata:s:s:1 language=eng -metadata:s:s:1 handler_name=English -metadata:s:s:1 title=English
But you need to know the final mapping which will depend on original files ab/presence of subtitles.
Credits to eladkarako.

Create muted video and black screen video with FFmpeg

I'm trying to use FFmpeg to generate the following from a local mp4 file:
A copy of the original video with no audio
A copy of the original video with audio but without visuals (a black screen instead). This file also needs to be in mp4 format.
After reading through the documentation I am struggling to get the terminal commands right. To remove the audio I have tried this command without any success:
ffmpeg -i file.mp4 -map 0:0 -map 0:2 -acodec copy -vcodec copy
Could anyone guide me towards how to accomplish this?
Create black video and silent audio
Use the color and anullsrc filters. Example to make 10 second output, 1280x720, 25 frame rate, stereo audio, 44100 sample rate:
ffmpeg -f lavfi -i color=size=1280x720:rate=25:color=black -f lavfi -i anullsrc=channel_layout=stereo:sample_rate=44100 -t 10 output.mp4
Remove audio
Only keep video:
ffmpeg -i input.mp4 -map 0:v -c copy output.mp4
Keep everything except audio:
ffmpeg -i input.mp4 -map 0 -map -0:a -c copy output.mp4
See FFmpeg Wiki: Map for more info on -map.
Make video black but keep the audio
Using the drawbox filter.
ffmpeg -i input.mp4 -vf drawbox=color=black:t=fill -c:a copy output.mp4
Generate silent audio
See How to add a new audio (not mixing) into a video using ffmpeg? and refer to the anullsrc example.
To remove the audio you can use this:
ffmpeg -i file.mp4 -c copy -an file-nosound.mp4
notice the -an option
-an (output)
Disable audio recording.
To keep audio but "replace" the video with a black screen, you could do this:
ffmpeg -i file.mp4 -i image.png -filter_complex overlay out.mp4
image.png is a black wallpaper that is placed on top of the video, but there should be better ways of full removing the frames, you could either extract the audio and later create a new video with the audio as a background

Resources