Ffmpeg Ignore stream if it doesn't exist - ffmpeg

I'm using ffmpeg to convert files to .mp3 and extract cover images from the metadata.
This works fine for files that have cover images, files that don't throw the error:
Output #1 does not contain any stream
ffmpeg -i kalimba.mp3 -y test.mp3 -acodec copy test.jpg
How can I tell ffmpeg to just ignore streams if they don't exist and continue converting to .mp3 if no cover image exists in the metadata?

First you should check what streams are provided in the file. You can do it with tool ffprobe. Then you run ffmpeg to copy one or two streams.
if [ -n "`ffprobe -show_streams -v quiet kalimba.mp3 | grep '^\[streams\.stream\.1\]'`" ] ; then
# the file has 2 streams
ffmpeg -i kalimba.mp3 -y test.mp3 -acodec copy test.jpg
else
# no cover image
ffmpeg -i kalimba.mp3 -y test.mp3 -acodec copy
fi

Related

merge audio and video with ffmpeg doesnt work correctly

I have ubuntu 20.04 and in past days I did this job(merge video and audio) well in terminal and with ffmpeg:
ffmpeg -i input.mp4 -i input2.mp3 -c copy output.mp4
so fast I have recived output.mp4, but now I tried this one and get output without any sound!
I try another ways to merge this ones(also with ffmpeg) but there are no diffrent...
ffmpeg -f concat -safe 0 -i <(for f in ./input*.mp4; do echo "file '$PWD/$f'"; done) -c copy output.mp4
Note -f concat will select a demuxer. This alters the way -i nput files are read.
So instead video-files 'concat expects a txt-file listing the files to concatenate.
However we somehow omit the creation of that text file and use process substitution to generate and pass that list on the fly to demux.
For more details go here:
https://trac.ffmpeg.org/wiki/Concatenate#demuxer
If you want to merge several video files, you can use these command.
merge two video files.
ffmpeg -f concat -i 1.mp4 -1 2.mp4 -codec copy out.mp4
merge multiple video files.
ffmpeg -i 1.mp4 -i 2.mp4 -i 3.mpt -vcodec copy -acodec copy out.mp4

Add subtitles to multiple files at once

I have a folder with episodes called ep and a folder with subtitles called sub
Each episode has corresponding subtitles and i need to bulk add them with ffmpeg.
I've read that i can add subtitles with the following command:
ffmpeg -i video.avi -vf "ass=subtitle.ass" out.avi
But that only does it one file at a time.
Is there a bulk variant?
Some useful info:
ls ep prints
<series name> - Ep<episode number>.mkv
ls sub prints
<series name> - Ep<episode number>.ass
I made a small sh script that will do this:
#!/bin/sh
SUBTITLES_FOLDER=sub
EPISODES_FOLDER=ep
OUTPUT_FOLDER=out
for i in "$EPISODES_FOLDER"/*.mkv; do
sub="$SUBTITLES_FOLDER/$(echo "$i" | sed 's/mkv$/ass/')"
ffmpeg -i "$i" -i "$sub" -c:v copy -c:a copy -c:s copy -map 0:0 -map 0:1 -map 1:0 -y "$OUTPUT_FOLDER/$i" &
done
Note the '&' at the end of the ffmpeg command: it makes sure ffmpeg runs in parallel (is this the correct term for it?)
You may want to modify the file extensions and check if ffmpeg supports subtitles with your format, the rest will be done by itself.

extract audio using ffmpeg and save wav files

ffmpeg has a way to extract video images using the following command
ffmpeg -i "video.avi" -vf fps=30 "images/frame_%09d.png" -hide_banner
Is there a way in ffmpeg to extract or cut audios into smaller chunks the same way that is done on the above command but the difference is it will create an audio file not an image file.
I tried the following but it only creates a wav file.
ffmpeg -i "video.avi" -vf fps=30 "images/frame_%09d.wav" -hide_banner
Remove -vf option, you don't need it as you don't need video
Video frames can be assumed as single units, but what you want in audio? Sungle samples. huh? So, you must specify interval
For example:
# ffmpeg -i "video.avi" -f segment -segment_time 3 -c copy "images/frame_%03d.mp3" -hide_banner

ffmpeg converting from mkv to mp4 without re-encoding

I am using ffmpeg to switch container from mkv to mp4 via this command:
ffmpeg -i filename.mkv -vcodec copy 1.mp4
this is the simplest command that I found when converting from mkv container to mp4 without re-encoding. The output stated otherwise (if I am not mistaken)
This is a small screen shot of the the output:
Where it said Stream Mapping, #0:0 (264 (native)) -> 264 (libx264)). Does this mean that it's re-encoding from x264 to libx264? What Did I do wrong?
Any help is appreciated...
problem solved, specify the audio codec solve my problem...
ffmpeg -i filename.mkv -vcodec copy -acodec copy 1.mp4
Remuxing containers, e.g. MKV or AVI to MP4, with FFmpeg will only keep a single – it tries to choose the best one available – audio and video stream from the input file in the output file. This can be avoided by providing -map 0.
Matroska files frequently contain subtitles in a format not supported in MOV/MPEG containers by FFmpeg, esp. SRT/Subrip or ASS/SSA. They can either simply be dropped with -sn or be converted to a native format like mov_text. (You could also burn hard subtitles into a video stream with filters.)
Sometimes, adding missing information by using heuristics might help. This is activated with -find_stream_info, but I am not sure whether this should be used by default.
I shall assume that built configuration is not important to know (-hide_banner) and only serious problems should be logged to the console (-loglevel warning, alternatively: quiet | panic | fatal | error | warning | info (default) | verbose | debug | trace).
Therefore, a rather universal conversion command looks like this:
$ ffmpeg -find_stream_info -i input.mkv \
-map 0 -codec copy -codec:s mov_text output.mp4 \
-hide_banner -loglevel warning; \
rm input.mkv
For batch processing multiple files on a Windows box within cmd and overwriting existing files (-y), use for:
FOR /r %F IN (*.mkv) DO (#ffmpeg \
-find_stream_info -i "%F" \
-map 0 -codec copy -codec:s mov_text "%~pnF.mp4" \
-hide_banner -loglevel warning -y)
ffmpeg.exe -i input_file_name.mkv output_file_name.mp4
It converts to mp4 but it making a bigger size. :)
For those who use Windows and want to convert a directory of MKV files, throw this batch file in the same directory and execute it:
#ECHO OFF
FOR %%F IN (*.mkv) DO (
ffmpeg -i %%~nF.mkv -acodec copy -vcodec copy %%~nF.mp4
)
Some context in case anyone else is facing the same:
I'd previously recorded my desktop using OBS; the mkv file wasn't accepted by Sony Vegas. I ran the above batch which called ffmpeg on each of the captures and the resultant MP4s were accepted by Sony Vegas.

Run ffmpeg multiple commands

Im using this ffmpeg command to convert mp3 to wav:
ffmpeg -i audio.mp3 -acodec libmp3lame -ab 64k -ar 16000 audio.wav
and this command to create waveform from audio.wav:
wav2png --foreground-color=ffb400aa --background-color=2e4562ff -o example4.png papa2.wav
I would love to know, how to run this commands multiple? For example, when conversion from .mp3 to .wav is done, then run the wav2png command.
Thank You!
You have several options here:
Option 1: Use &&
In Bash you can use an and list to concatenate commands. Each command will be executed one after the other. The and list will terminate when a command fails, or when all commands have been successfully executed.
ffmpeg -i audio.mp3 audio.wav && wav2png -o output.png audio.wav
Using -acodec libmp3lame when outputting to WAV makes no sense, so I removed that.
WAV ignores bitrate options, so I removed -ab.
Do you really need to change the audio rate (-ar)? Removed.
Option 2: Pipe from ffmpeg to wav2png
Instead of making a temporary WAV file you can pipe the output from ffmpeg directly to wav2png:
ffmpeg -i audio.mp3 -f wav - | wav2png -o output.png /dev/stdin
Option 3: Just use ffmpeg
Saving the best for last, you can try the showwavespic filter.
ffmpeg -i music.wav -filter_complex showwavespic=s=640x320 showwaves.png
If you want to make a video of the wave form, then try showwaves.
You can see a colored example at Generating a waveform using ffmpeg.

Resources