Adding multiple audio tracks and subtitles to dash manifest (mpd) with ffmpeg - ffmpeg

I'm trying to create a website to stream some videos. For each video, I extract video, audio and subtitles in 3 different folders. It happens that a video has multiple audio tracks and multiple subtitles. I did a lot of research and I don't know how to add all of them in the manifest. Right now, I use this command:
ffmpeg -f webm_dash_manifest \
-i video1.mp4 -f webm_dash_manifest \
-i video2.mp4 -f webm_dash_manifest \
-i audio1.webm -f webm_dash_manifest \
-i audio2.webm -f webm_dash_manifest \
-i subtitles.vtt \
-c copy -map 0 -map 1 -map 2 -map 3 \
-f webm_dash_manifest -adaptation_sets "id=0,streams=v id=1,streams=a" manifest.mpd
My two videos have different resolutions and bitrates, and it works perfectly. But I don't get any subtitles and my two audio tracks are considered like one same audio track which has two different bitrates (just like videos). I think I should have many adaptation_sets, but I don't know how to create them.
How can I create that manifest the right way?

After a few days, I found the solution.
My goal is to convert a video into mpeg-dash content which is really great for streaming.
I will encode video to h264, audio to aac, and subtitles to webvtt.
It's good settings for a large browser compatibility.
vp9 is really nice too but too long to encode for me.
Tools required:
ffmpeg: https://www.ffmpeg.org/download.html
mp4dash & mp4fragment: https://www.bento4.com/downloads/
Let's suppose we have a 1080p video file "video.mkv" with these streams:
0: video stream
1: audio stream, it language
2: audio stream, en langugage
3: subtitle stream, it language
4: subtitle stream, en language
1. Extracting differents streams
1.1 Video
I extract and transcode video stream to differents resolutions and bitrates:
ffmpeg -i video.mkv -an -sn -c:0 libx264 -x264opts 'keyint=24:min-keyint=24:no-scenecut' -b:v 5300k -maxrate 5300k -bufsize 2650k -vf 'scale=-1:1080' tmp/video/video-1080.mp4
ffmpeg -i video.mkv -an -sn -c:0 libx264 -x264opts 'keyint=24:min-keyint=24:no-scenecut' -b:v 2400k -maxrate 2400k -bufsize 1200k -vf 'scale=-1:720' tmp/video/video-720.mp4
ffmpeg -i video.mkv -an -sn -c:0 libx264 -x264opts 'keyint=24:min-keyint=24:no-scenecut' -b:v 600k -maxrate 600k -bufsize 300k -vf 'scale=-1:360' tmp/video/video-360.mp4
1.2 Audio
ffmpeg -i video.mkv -map 0:1 -ac 2 -ab 192k -vn -sn tmp/audio/audio-it.mp4
ffmpeg -i video.mkv -map 0:2 -ac 2 -ab 192k -vn -sn tmp/audio/audio-en.mp4
1.3 Subtitle
ffmpeg -i video.mkv -map 0:3 -vn -an tmp/subtitle/subtitle-it.vtt
ffmpeg -i video.mkv -map 0:4 -vn -an tmp/subtitle/subtitle-en.vtt
You can use the "-loglevel warning" option to see less informations.
2. Fragment video and audio
2.1 Video
mp4fragment tmp/video/video-1080.mp4 tmp/video/f-video-1080.mp4
mp4fragment tmp/video/video-720.mp4 tmp/video/f-video-720.mp4
mp4fragment tmp/video/video-360.mp4 tmp/video/f-video-360.mp4
2.2 Audio
mp4fragment tmp/audio/audio-it.mp4 tmp/audio/f-audio-it.mp4
mp4fragment tmp/audio/audio-en.mp4 tmp/audio/f-audio-en.mp4
3. Split files and create the dash manifest
mp4dash --mpd-name=manifest.mpd tmp/video/f-video-1080.mp4 tmp/video/f-video-720.mp4 tmp/video/f-video-360.mp4 tmp/audio/f-audio-it.mp4 tmp/audio/f-audio-en.mp4 \[+format=webvtt,+language=it\]tmp/subtitle/subtitle-it.vtt \[+format=webvtt,+language=en\]tmp/subtitle/subtitle-en.vtt
You can now delete the tmp folder
rm -rf tmp
(and your source file if you don't need it anymore)
You have now your mpeg-dash content which can be streamed. You have to serve your files (allow cors and enable byte range request).
I use angular and rx-player as player. I can switch language, subtitles and the video quality is adaptative to the client's bandwidth !
Rx-player: https://github.com/canalplus/rx-player

Related

How to get playing audio file data in ffmpeg stream?

Dears experts of the wonderful ffmpeg utility! Tell me please who knows this:
I want to make a 24/7 stream on YouTube of music from looped video and audio tracks.
I do it like this:
ffmpeg -loglevel info -stream_loop -1 -y -re \
-i video.mp4 \
-f concat -safe 0 -i playlist.txt \
-c:v libx264 -preset veryfast -b:v 3000k -maxrate 3000k -bufsize 6000k \
-framerate 25 -video_size 1280x720 -vf "format=yuv420p" -g 50 -shortest -strict experimental \
-c:a aac -b:a 128k -ar 44100 \
-f flv rtmp://localhost/live/my-stream
i.e. video.mp4 is spinning in a loop and from the playlist.txt file I play mp3 in turn.
With this everything is ok, everything works. But I also want to show the title of the playing track.
As for example on some YouTube radios:
With cover is perfect!
Any ideas how this can be implemented?
I know that it is possible to display text through drawtext. You can output text from a file, which you can separately update yourself. But how to get the data of the currently playing file? ffmpeg does not give such information, only stream parameters: fps, framerate... Or is it still possible to get it?
Or are there better and easier ways?
Thanks in advance for your help!
you can use FFprobe to extract metadata from files.

Combine Two Commands (Get Video from Images)

I have 300 images and i wants to generate video from these images.
i am new to FFMPEG so now i am using two commands to generate video from images.
Command to generate video from images which also add Logo on video
ffmpeg -framerate 24 -i img_%d.jpg -i logo.png -filter_complex \
"[0:v][1:v] overlay=25:25:enable='between(t,0,20)'" \
-vcodec libx264 -crf 25 -pix_fmt yuv420p test_video.mp4
After using above command i am getting the video to add audio to this video i am using below command
ffmpeg -i test_video.mp4 -i inputfile.mp3 -c:v libx264 -c:a libvorbis -shortest final_video.mp4
which generates video and i am getting below message
MPEG-4 AAC decoder is required to play the file
Help to combine this both command. if possible can we add sound without any decoder required
Log for command 1 https://drive.google.com/file/d/1zS7gvrPy69VK_MkyE4127FpX2kEziJHq/view?usp=sharing
and Log command 2 https://drive.google.com/file/d/1rHqVGzj7f003aWP6eISiyUjsES8_EWuw/view?usp=sharing
Try next command:
ffmpeg -framerate 24 -i img_%d.jpg -i logo.png -i inputfile.mp3 -filter_complex \
"[0:v][1:v] overlay=25:25:enable='between(t,0,20)'" \
-vcodec libx264 -crf 25 -map 2:a -c:a copy -pix_fmt yuv420p -shortest test_video.mp4
-map 2:a is needed to skip image in case if there is cover image in track.
With -c:a copy track will not be re-encoded, so you will have mp3 inside of your video file.

How to overlay a png to piped video source with audio mixed in via ffmpeg?

I'm successfully streaming silent video with music added from my Raspberry Pi (Raspbian) to YouTube via ffmpeg, with the help of this GitHub gist and this post:
raspivid -o - -t 0 -vf -hf -w 1280 -h 720 -fps 25 -b 4000000 | \
ffmpeg -i music.wav \
-f h264 -i - -vcodec copy -acodec aac -ab 128k -g 50 -strict experimental \
-f flv rtmp://a.rtmp.youtube.com/live2/STREAMKEY
The last step of my project to add a transparent, full width/height png overlay to the video (1280x720 size in my case). I've seen a few related answers such as this one and this one.
With the added complexity of piping in a camera feed, mixing in an audio source and outputting to a video stream, I haven't succeeded in adding the image overlay. Where/how would I add a transparent image overlay in the example above?
The ffmpeg part will be
ffmpeg -i music.wav \
-f h264 -i - -i overlay.png
-filter_complex "[1][2]overlay"
-vcodec libx264 -preset ultrafast -tune zerolatency -acodec aac -ab 128k -g 50 -strict experimental \
-f flv rtmp://a.rtmp.youtube.com/live2/STREAMKEY
Since you're altering the video contents, copy can't be used, and the video has to be re-encoded.

FFmpeg concat and then add soundtrack results in a soundtrack that stutters

I am trying to create a video composed of clips of images and videos. For the clips of images, I use ffmpeg to create a video file and then I add a silent audio stream through these two steps:
ffmpeg.exe -loop 1 -i MyImage.png -codec:v libx264 -t 4.0 -profile:v high -preset slow -r 25 -b:v 500k -maxrate 500k -pix_fmt yuv420p -vf scale=1280:720 MyImageMovie.mp4
ffmpeg.exe -f lavfi -i anullsrc=r=48000 -i MyImageMovie.mp4 -shortest -c:v copy -c:a aac -strict experimental -y MyImageMovieWithSilentAudioStream.mp4
Then I combine my video clips and image clips with
ffmpeg.exe -f concat -i videoList.txt -c copy -y concatVideo.mp4
At this point, the video looks good, any video clips that have audio streams seemed well synced to the video.
Now I add a soundtrack:
ffmpeg.exe -i concatVideo.mp4 -i soundtrack.mp3 -ar 48000 -filter_complex "[1:a]apad [b] ; [0:a][b]amerge=inputs=2[a]" -map 0:v -map "[a]" -c:v copy -ac 2 -shortest -y FinalVideo.mp4
The problem is that the soundtrack on FinalVideo.mp4 stutters at some (not all) of the concatenation joints.
I suspect it has to do with the audio stream and the video stream of the Image clips not being perfectly aligned. The aac has .0231s resolution and the video has 0.04s resolution. When I ffprobe the MyImageMovieWithSilentAudioStream.mp4 the duration is 4.00s but the start is 0.0213.
If my concatenated video has several of these image clips, the error can start to accumulate.
What can I do to keep the video and audio in sync and add a soundtrack that doesn't stutter?
Also, this is a little interesting, I don't hear the stutter when the final video is played on Windows Media Player, but it is there if I play it on VLC or via the html native video element.
Try adding the soundtrack in the same step as the concat.
ffmpeg -f concat -i videoList.txt -i soundtrack.mp3 \
-filter_complex "[1:a]apad[b];[0:a][b]amerge=inputs=2[a]" \
-map 0:v -map "[a]"
-c:v copy -c:a aac -ac 2 -ar 48000 -shortest -y FinalVideo.mp4
As an aside, you can also combine the image and silent stream generation,
ffmpeg -loop 1 -i MyImage.png -f lavfi -i anullsrc=r=48000 \
-vf scale=1280:720 \
-c:v libx264 -profile:v high -preset slow -r 25 -b:v 500k -maxrate 500k -pix_fmt yuv420p \
-c:a aac -strict experimental -t 4 -y MyImageMovieWithSilentAudioStream.mp4

ffmpeg converted .mp4 videos are not playing on windows

I am converting videos with extension "flv","avi","mp4","mkv", "mpg", "wmv", "asf", "webm","mov","3gp","3gpp" into "mp4" for a better quality.
Command I am using:
ffmpeg -i <server_path>/g9zyy2qg54qp1l5spo2-mergedFile.webm -strict -2 -vcodec libx264 -preset slow -vb 500k -maxrate 500k -bufsize 1000k -vf 'scale=-1:480 ' -threads 0 -ab 64k -s 640x480 -movflags faststart -metadata:s:v:0 rotate=0 <server_path>/g9zyy2qg54qp1l5spo2-mergedFile7.mp4
Videos are working fine everywhere except on Windows. No Video is working on window platform. I tried playing them on firefox, opera, even downloaded them and played on media player software but didn't work at all.
Can you please tell me codecs I should use that make the videos play on windows as well?
My video gets played in Windows 10 after adding parameters about pix_fmt and resolution (width and height should be even number):
ffmpeg -i temp-%d.png -c:v libx264 -strict -2 -preset slow -pix_fmt yuv420p -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" -f mp4 output.mp4
Use
"ffmpeg -i {$audioFile} -i {$videoFile} -map 1:0 -map 0:0 -strict -2 -vcodec libx264 -preset slow -vb 500k -maxrate 500k -bufsize 1000k -vf 'scale=-1:480 ' -threads 0 -ab 64k -s 640x480 -movflags +faststart -metadata:s:v:0 rotate=0 -fflags +genpts <server_path>/g9zyy2qg54qp1l5spo2-mergedFile7.mp4
(this uses the original command in your question)
Found a fix here convert webm to mp4. Now after getting merged webm file I am converting it to mp4 using command "ffmpeg -fflags +genpts -i 1.webm -r 24 1.mp4". This mp4 file is playing in window browsers.
For the above process I have to use 2 ffmpeg commands.
1.To make merge audio/video file into 1 webm file and
"ffmpeg -i {$audioFile} -i {$videoFile} -map 0:0 -map 1:0 -strict -2 {$mergedFileName}"
To make mp4 file.
"ffmpeg -fflags +genpts -i {$mergedFile} -strict -2 -r 24 {$mp4File}"
Can I club above 2 commands which input audio & video files to give me single mp4 file?
Edit:
I have clubbed the above 2 commands
"ffmpeg -fflags +genpts -i {$videoFile} -i {$audioFile} -strict -2 -r 24 {$mp4File}"
Its working well for me. The result mp4 video is playing in window 7 (chrome, firefox, opera) browsers. Also working in Linux (firefox, Opera ) browsers.

Resources