I want to convert several video files (captured from television) to another format, but I want to remove some specific streams. For example, this is one of my input files:
$ ffprobe -hide_banner -i 'Easy Rider.ts' 2>&1|grep Stream
Stream #0:0[0x4f6]: Unknown: none ([5][0][0][0] / 0x0005)
Stream #0:1[0x4fc]: Unknown: none ([12][0][0][0] / 0x000C)
Stream #0:2[0x13f7]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(progressive), 1280x720 [SAR 1:1 DAR 16:9], 50 fps, 50 tbr, 90k tbn, 100 tbc
Stream #0:3[0x13f8](deu): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 192 kb/s
Stream #0:4[0x13f9](fra): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 192 kb/s
Stream #0:5[0x13fa](deu): Subtitle: dvb_teletext ([6][0][0][0] / 0x0006)
Stream #0:6[0x13fb](deu): Subtitle: dvb_subtitle ([6][0][0][0] / 0x0006) (hearing impaired)
Stream #0:7[0x13fc](mul): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 192 kb/s
Stream #0:8[0x13fd](mis): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 192 kb/s (visual impaired) (descriptions)
Stream #0:9[0x13fe](fra): Subtitle: dvb_subtitle ([6][0][0][0] / 0x0006)
Stream #0:10[0x13ff](deu): Subtitle: dvb_subtitle ([6][0][0][0] / 0x0006)
From this file, I want to keep
Stream #2 (h264 video)
Stream #3 (mp2 audio in german)
Stream #10 (dvb_subtitle in german)
In other words, I want to exclude from conversion
all streams of unknown type
all audio streams other than german
all streams for visual impaired or hearing impaired
all dvb_teletext streams
Of cause, I can do some awk scripting to construct a command like
$ ffmpeg -hide_banner -ignore_unknown -i 'Easy Rider.ts' -map 0:2 -map 0:3 -map 0:10 -vcodec copy -acodec copy -scodec copy xx.ts
But I am searching for a solution using ffmpeg's mapping facilities.
I already found Mapping streams by language in FFmpeg, which led me to
$ ffmpeg -hide_banner -ignore_unknown -i 'Easy Rider.ts' -map 0:v -map 0:m:language:deu -vcodec copy -acodec copy -scodec copy xx.ts
This command creates a file, which still has subtitles for hearing impaired and the dvb_teletext in it
$ ffprobe -hide_banner -i xx.ts 2>&1|grep Stream
Stream #0:0[0x100]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(progressive), 1280x720 [SAR 1:1 DAR 16:9], 50 fps, 50 tbr, 90k tbn, 100 tbc
Stream #0:1[0x101](deu): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 192 kb/s
Stream #0:2[0x102](deu): Subtitle: dvb_teletext ([6][0][0][0] / 0x0006), 492x250
Stream #0:3[0x103](deu): Subtitle: dvb_subtitle ([6][0][0][0] / 0x0006) (hearing impaired)
Stream #0:4[0x104](deu): Subtitle: dvb_subtitle ([6][0][0][0] / 0x0006)
Up to now, I did not find a way to exclude those streams from the output. Any idea?
Related
ffmpeg -framerate 1 -loop -1 -i image.jpg -i audio.wav -shortest out.mp4
Using ffmpeg version 2022-02-24-git-8ef03c2ff1-full_build-www.gyan.dev
Here is the ffprobe for audio.wav
Input #0, wav, from 'audio.wav': Duration: 00:00:20.21, bitrate:
1411 kb/s Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001),
44100 Hz, 2 channels, s16, 1411 kb/s
and out.mp4 (note that the duration is 1:20, instead of the 20 second duration of the audio file).
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'out.mp4': Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf59.17.102 Duration: 00:01:20.00, start: 0.000000, bitrate: 156 kb/s Stream #0:00x1: Video: h264 (High 4:4:4 Predictive) (avc1 / 0x31637661), yuvj444p(pc,
bt470bg/unknown/unknown, progressive), 1200x1443 [SAR 1:1 DAR
400:481], 120 kb/s, 1 fps, 1 tbr, 16384 tbn (default)
Metadata:
handler_name : VideoHandler
vendor_id : [0][0][0][0] Stream #0:10x2: Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 139 kb/s
(default)
Metadata:
handler_name : SoundHandler
vendor_id : [0][0][0][0]
I have one video file .mkv.
Inside this file, there is a video track, 3 audio tracks, 2 subtitles, a poster file, and a backdrop file.
Does ffmpeg know how to split .mkv into separate parts, video / 3 audio / 2 subtitles?
~# ffmpeg -hide_banner -i input.mkv
Input #0, matroska,webm, from 'input.mkv':
Duration: 01:37:03.90, start: 0.000000, bitrate: 3605 kb/s
Metadata:
title : 01:33:51.582
Stream #0:0(eng): Video: h264 (High), yuv420p(tv, bt709, progressive), 1024x576 [SAR 1:1 DAR 16:9], 23.98 fps, 23.98 tbr, 1k tbn, 47.95 tbc (default)
Metadata:
title : Video
Stream #0:1(rus): Audio: ac3, 48000 Hz, 5.1(side), fltp, 448 kb/s (default)
Metadata:
title : MVO «West Video»
Stream #0:2(spa): Audio: ac3, 48000 Hz, stereo, fltp, 192 kb/s
Metadata:
title : MVO Spain-1
Stream #0:3(eng): Audio: ac3, 48000 Hz, stereo, fltp, 192 kb/s
Metadata:
title : MVO TRK
Stream #0:4(eng): Subtitle: subrip (default)
Metadata:
title : RUS
Stream #0:5(eng): Subtitle: subrip
Metadata:
title : Eng
Stream #0:6(und): Video: mjpeg (Progressive), yuvj420p(pc, bt470bg/unknown/unknown), 780x1170 [SAR 1:1 DAR 2:3], 90k tbr, 90k tbn, 90k tbc (attached pic)
Metadata:
filename : poster.jpg
mimetype : image/jpeg
title : poster
LANGUAGE : und
Stream #0:7(und): Video: mjpeg (Progressive), yuvj420p(pc, bt470bg/unknown/unknown), 1280x719 [SAR 1:1 DAR 1280:719], 90k tbr, 90k tbn, 90k tbc (attached pic)
Metadata:
filename : backdrop.jpg
mimetype : image/jpeg
title : backdrop
LANGUAGE : und
I need:
Video
input0.mp4
Audio
input0.m4a
input1.m4a
input2.m4a
Subtitle
input0.vtt
input1.vtt
These commands do the splitting, but I need to know exactly how many audio files and how many subtitle files are in the mkv.
ffmpeg -y -i input.mkv \
-map 0:v:0 -c:v libx264 output0.mp4
ffmpeg -y -i input.mkv \
-map 0:a:0 -c:a aac output0.m4a \
-map 0:a:1 -c:a aac output1.m4a \
-map 0:a:2 -c:a aac output2.m4a
ffmpeg -y -i input.mkv \
-map 0:s:0 output0.vtt \
-map 0:s:1 output1.vtt
Is it possible to make such divisions without knowing the file number 0:a:2, 0:s:1?
I am trying to concatenate multiple files together using ffmpeg concatenate demuxer. However final video is out of sync.
First parts are coming from static image which are converted to 5-seconds video in the following way:
ffmpeg -r 30 -i 1.png -vf loop=loop=150:size=1:start=0 -pix_fmt yuv420p -c:v libx264 -preset superfast -tune stillimage loop.mp4
Then I add silent audio stream:
ffmpeg -i loop.mp4 -f lavfi -i anullsrc -map 0:v -map 1:a -ar 44100 -ac 2 -c:v copy -c:a aac -shortest silent.mp4
ffrobe for the silent.mp4:
ffprobe -v quiet -show_entries stream=start_time,duration silent.mp4
[STREAM]
start_time=0.000000
duration=5.733333
[/STREAM]
[STREAM]
start_time=0.000000
duration=5.665011
[/STREAM]
Which already shows that audio and video streams have different duration.
Then I prepare concat input file, last line is the video with same dimension and framerate, also it has existing audio stream (44.1kHz, stereo)
file silent.mp4
file silent.mp4
... (multiple lines, say 10)
file silent.mp4
file video.mp4
To make sure that inputs have same parameters:
ffmpeg -i silent.mp4 -i video.mp4
ffmpeg version 4.2.2 Copyright (c) 2000-2019 the FFmpeg developers
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'silent.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.29.100
Duration: 00:00:05.03, start: 0.000000, bitrate: 32 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], 19 kb/s, 30 fps, 30 tbr, 15360 tbn, 60 tbc (default)
Metadata:
handler_name : VideoHandler
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 2 kb/s (default)
Metadata:
handler_name : SoundHandler
Input #1, mov,mp4,m4a,3gp,3g2,mj2, from 'video.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.29.100
Duration: 00:00:43.03, start: 0.000000, bitrate: 1622 kb/s
Stream #1:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1920x1080, 1484 kb/s, 30 fps, 30 tbr, 15360 tbn, 60 tbc (default)
Metadata:
handler_name : VideoHandler
Stream #1:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 128 kb/s (default)
Metadata:
handler_name : SoundHandler
Now, after concatenation final video is out of sync with audio (audio stream of the last part starts before static part is finished)
ffmpeg -f concat -i concat.txt -c copy result.mp4 (no warnings)
I have tried to pad audio stream with silence in both loop.mp4 and video.mp4, but it did not help - it randomly modifies duration and start time of both video and audio streams and audio is again out of sync after concat.
Also, I am not able to increase the duration of static part (so that number of entries in concat.txt can be decreased) because each static part can be different - this is just an example.
I have an mp4 file like this(same format but longer):
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'N1.2.mp4':
Metadata:
major_brand : mp42
minor_version : 0
compatible_brands: mp42mp41
creation_time : 2018-10-31T13:44:21.000000Z
Duration: 00:28:54.21, start: 0.000000, bitrate: 10295 kb/s
Stream #0:0(eng): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, bt709), 1920x1080, 9972 kb/s, 50 fps, 50 tbr, 50k tbn, 100 tbc (default)
Metadata:
creation_time : 2018-10-31T13:44:21.000000Z
handler_name : ?Mainconcept Video Media Handler
encoder : AVC Coding
Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 317 kb/s (default)
Metadata:
creation_time : 2018-10-31T13:44:21.000000Z
handler_name : #Mainconcept MP4 Sound Media Handler
I also have another video file that is 3 minutes long. and has no audio. What is the fastest way to encode the other video in a way that it is encoded like my main video and then replace the last three minutes of the video track of my original video with this?
In other words.
I have video A that is 1 hour long. With the encoding shown above.
I have video B that is 3 minutes long with no audio. with a random encoding.
I want to have video C with the same encoding and same audio as A. But it's video track would be the first 57 minutes of A + B(which is 3 minutes).
I want to do this as fast as possible so I would like to not re encode A.
I know how to concatenate two videos, I use this command:
ffmpeg -f concat -i files.txt -c copy res.mp4
Make end video using parameters of main video:
ffmpeg -i videob.mp4 -f lavfi -i anullsrc=sample_rate=48000:channel_layout=stereo -filter_complex "[0:v]scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,setsar=1,format=yuv420p,fps=50[v]" -map "[v]" -map 1:a -c:v libx264 -profile:v main -c:a aac -video_track_timescale 50000 -shortest videob2.mp4
Get duration of main video:
ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 main.mp4
Make files.txt which is needed for concat demuxer:
file 'main.mp4'
outpoint 3420
file 'videob2.mp4'
In this example outpoint is main video duration minus end video duration.
Concatenate:
ffmpeg -f concat -i files.txt -i main.mp4 -map 0:v -map 1:a -c copy -shortest output.mp4
To capture my pc screen with following ffmpeg command.
ffmpeg -f pulse -ac 2 -i default -f x11grab -r 30 -s 1920x1080 -i :0.0 -acodec pcm_s16le -vcodec libx264 -preset ultrafast -threads 0 -y /tmp/output.mkv
The output displayed on my console when to execute the above command.
Guessed Channel Layout for Input Stream #0.0 : stereo
Input #0, pulse, from 'default':
Duration: N/A, start: 1515543051.106987, bitrate: 1536 kb/s
Stream #0:0: Audio: pcm_s16le, 48000 Hz, stereo, s16, 1536 kb/s
[x11grab # 0x564bda5b8520] Stream #0: not enough frames to estimate rate; consider increasing probesize
Input #1, x11grab, from ':0.0':
Duration: N/A, start: 1515543052.415508, bitrate: N/A
Stream #1:0: Video: rawvideo (BGR[0] / 0x524742), bgr0, 1920x1080, 30 fps, 1000k tbr, 1000k tbn, 1000k tbc
No pixel format specified, yuv444p for H.264 encoding chosen.
Use -pix_fmt yuv420p for compatibility with outdated media players.
[libx264 # 0x564bda5c1560] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 LZCNT
[libx264 # 0x564bda5c1560] profile High 4:4:4 Predictive, level 4.0, 4:4:4 8-bit
[libx264 # 0x564bda5c1560] 264 - core 148 r2748 97eaef2 - H.264/MPEG-4 AVC codec - Copyleft 2003-2016 - http://www.videolan.org/x264.html - options: cabac=0 ref=1 deblock=0:0:0 analyse=0:0 me=dia subme=0 psy=1 psy_rd=1.00:0.00 mixed_ref=0 me_range=16 chroma_me=1 trellis=0 8x8dct=0 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=6 threads=3 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=0 weightp=0 keyint=250 keyint_min=25 scenecut=0 intra_refresh=0 rc=crf mbtree=0 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=0
Output #0, matroska, to '/tmp/output.mkv':
Metadata:
encoder : Lavf57.56.101
Stream #0:0: Video: h264 (libx264) (H264 / 0x34363248), yuv444p, 1920x1080, q=-1--1, 30 fps, 1k tbn, 30 tbc
Metadata:
encoder : Lavc57.64.101 libx264
Side data:
cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: -1
Stream #0:1: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 48000 Hz, stereo, s16, 1536 kb/s
Metadata:
encoder : Lavc57.64.101 pcm_s16le
Stream mapping:
Stream #1:0 -> #0:0 (rawvideo (native) -> h264 (libx264))
Stream #0:0 -> #0:1 (pcm_s16le (native) -> pcm_s16le (native))
Playing a music when to make the screenshot,i can hear the music playing lound.
It's strange that vedio came out perfectly without sound when to play the captured /tmp/output.mkv.
Open my volume control with pavucontrol.
Nothing in recording window, maybe the blank recording window result in no souond when to capture screen!
How to fix it ?
Solved.
ffmpeg -f pulse -ac 2 -i default -f x11grab -r 30 -s 1920x1080 -i :0.0 -acodec pcm_s16le -vcodec libx264 -preset ultrafast -threads 0 -y /tmp/test.avi
To change output file format from test.mkv as test.avi .