FFMPEG is doubling audio length when extracting from video - ffmpeg

I've got a video file, video.mp4. It is 18 minutes 23 seconds in duration. I am looking to extract the audio only from this video, and create an MP3 of the highest possible quality from the audio in the video.
Some googlefu lead me to this command: ffmpeg -i video.mp4 audio.mp3
The problem is that, this command doubles the length of the audio that's outputted (duration is 36 minutes 46 seconds). It loops the audio track once, so the output contains the entire 18 minutes 23 seconds of audio, then immediately starts the 18 minutes and 23 seconds of audio over again.
Some more googlefu lead me to this flag: -write_xing 0 from this SO question, but even with that flag it still loops the audio.
EDIT: Additional googlefu and me seeming to think it has something to do with 2 audio channels (and perhaps looping channel 2 immediately after channel 1, rather than merging the two) lead me to this flag: -ac 1 to force it to merge stereo -> mono. This did not work also, and it still outputs a 38 minute 46 seconds MP3 file.
How can I extract (to MP3) the audio from a video file, without doubling the duration?

Your googlefu must be malfunctioning.
If you have a single audio track:
ffmpeg -i movie.mp4 -map 0:a -c:a mp3 audio.mp3
If you have multiple audio tracks:
Identify the track:
ffprobe -i movie.mp4 and look for an audio Stream #0:x where x is an integer
Use the above command using -map 0:x. Example for x = 2:
ffmpeg -i movie.mp4 -map 0:2 -c:a mp3 audio.mp3
How to use the -map option

Related

ffmpeg how to show each frame for 1 second?

I have a video, recorded at 7 fps. It's 17 seconds long and has 122 frames.
I want to keep all frames but show them 1 per second, I want the same video to last 122 seconds. I don't want to lose information, but I also don't want the file size to increase.
How can I do that? All the ffmpeg options I see change the frame rate but keep the duration or create/drop frames.
You want to slow down your video without reincoding your video to (possibly) keep the file size. You must strip the timestamps by exporting the video to a raw bitstream format:
ffmpeg -i input.mp4 -map 0:v -c:v copy -bsf:v h264_mp4toannexb raw.h264
and than remux it with:
ffmpeg -fflags +genpts -r 1 -i raw.h264 -c:v copy output.mp4
-r 1 sets the framerate to 1.

ffmpeg: How to keep audio synced when doing many (100) cuts with filter select='between(t,start,stop)+between...'

I am cutting out silent parts of a 45 minute video (a lecture).
To do this, I use a filter to select, say one hundred, non-silent parts (I already know their start and end times).
ffmpeg -i in.mp4
-vf "select='between(t,start_1,stop_1)+...+between(t,start_100,stop_100)', setpts=N/FRAME_RATE/TB"
-af "aselect='between(t,start_1,stop_1)+...+between(t,start_100,stop_100)', asetpts=N/SR/TB"
-c:a aac -c:v libx264 out.mp4
It works, but at the end of the video the images are delayed relative to the audio.
After reading this answer I also added
-shortest -avoid_negative_ts make_zero -fflags +genpts
at the end of the command. It didn't help.
As audio and video are concatenated independently I'm not surprised that tiny time errors due to finite frame rate add up.
Is there a solution that doesn't involve saving every non-silent part as a file?

Ffmpeg: add a short audio at the end of a mp4 video

What would be the command to add a short audio at the end of a video mp4?
Let's say the overlay audio lasts 3 sec. My video last 26 min.
At 25:50 min (video duration - 10 sec) the overlay audio starts. The original audio of the video is silenced for 3 sec meanwhile the overlay audio runs. Then the original video sound comes back after 3 sec.
Basic syntax is
ffmpeg -i video -i audio \
-filter_complex "[0]volume=0:enable='between(t,1550,1553)'[v];\
[1]adelay=1550000|1550000,apad[a];\
[v][a]amix=duration=first:dropout_transition=0,volume=2[mix]"
-map 0:v -map '[mix]' -c:v copy output

ffmpeg : mix audio and video of different length

I have 2 files: 1 video file (without sound) - length 6 seconds, 1 audio - length 10 seconds.
Both audio and video contains same conversation, but audio starts 4 seconds earlier and after that was started video.
[----------] audio
[------] video
So, I want to mix them together to video file with length 10 seconds where first 4 seconds black screen with audio then goes real video and audio.
[====------] audio+video (where '=' is black screen)
I hope my description was clear enough ).
How can I do this with ffmpeg or gstreamer ?
Let's say the video's resolution is WxH and framerate is F, and the difference in durations is D seconds, then the command is
ffmpeg -i video.mp4 -i audio.mp3 -f lavfi -i color=s=WxH:r=F -filter_complex
"[0]setpts=PTS-STARTPTS+D/TB[v];[2][v]overlay=eof_action=endall[vid]"
-map "[vid]" -map 1:a output.mp4

FFmpeg Slideshow issues

trying to get my head around ffmpeg to create a slideshow where each image is displayed for ~5 seconds with some audio. created a bat file to run the following so far:
ffmpeg -f image2 -i image-%%03d.jpg -i music.mp3 output.mpg
It gets the images and displayes them all very fast in the first second of the video, it then plays out the rest of the audio while showing the last image.
I want to make the images stay up longer (about 5 seconds), and stop the video after the last frame (not playing the rest of the song), are either of these things possible? i could hack the frame rate thing i guess by having hundreds of the same image in order to keep it up longer, but this is far from ideal!
Thanks
The default encoder for mpg output, mpeg1video, is strict about the allowed frame rates, so an input and an output -r are required:
ffmpeg -r 1/5 -i image-%03d.jpg -i music.mp3 -r 25 -qscale:v 2 -shortest -codec:a copy output.mpg
The input images will have a frame rate of 1 frame every 5 seconds and the output will duplicate frames to reach 25 frames per second.
-f image2 is generally not required.
-qscale:v can control output quality. A sane range is 2-5.
-shortest will make the output duration the same as the shortest input duration.
-codec:a copy copy your MP3 audio instead of re-encoding.
MPEG-1 video has more modern alternatives. See the FFmpeg and x264 Encoding Guide for more info.
Also see:
* FFmpeg FAQ: How do I encode single pictures into movies?
* FFmpeg Wiki: Create a video slideshow from images
You could use the filter fps instead of output framerate
ffmpeg -r 1/5 -i img%03d.png -i musicfile -c:v libx264 -vf fps=25 -pix_fmt yuv420p out.mp4
This however skips the last image for me strangely.

Resources