Is there a way to tell ffmpeg and/or avconv to use for the output the same codec as the one the input is encoded with, but do the transcoding?
I'm looking for something like:
ffmpeg -i input.mp4 -vcodec same_as_input output.mp4
Note that I'm not looking for -vcodec copy
, as that would copy the stream without transcoding. I want it to do the transcoding but use the same codec the input file is encoded with.
Also, if possible, I'd like to have the same for every possible parameter, that is: use the same bitrate, frame size, etc, take the value for every possible parameter from one given input file, rather than using any other defaults.
The above example may seem stupid because it's oversimplified (the result would be the same as copying), but imagine I add some processing, e.g. a start time and length, or even something more complex such as adding an overlay image, but I want to make sure it's encoded with the same encoder (and possibly the same parameters) as the input file.
ffmpeg
doesn't have a feature to copy the same bitrate, but it will automatically copy the frame rate, width, height, pixel format, aspect ratio, audio channel count, audio sample rate, etc, (encoder dependent).
I don't recommend copying the same bitrate for a variety of reasons that would end up as several paragraphs. In short, let the encoder deal with that automatically.
However, here is a simple bash script. You'll need to adapt it to include audio stream info and whatever other parameters you want.
#!/bin/bash
# Copies the same video codec and bitrate: usually this is not a good idea.
# Usage: ./vidsame input output
echo "Calculating video bitrate. This can take a while for long videos."
# Alternatively you could just use ffprobe to get video stream bitrate,
# but not all inputs will show stream bitrate info, so ffmpeg is used instead.
size="$(ffmpeg -i "$1" -f null -c copy -map 0:v:0 - |& awk -F'[:|kB]' '/video:/ {print $2}')"
codec="$(ffprobe -loglevel error -select_streams v:0 -show_entries stream=codec_name -of default=nk=1:nw=1 "$1")"
duration="$(ffprobe -loglevel error -select_streams v:0 -show_entries format=duration -of default=nk=1:nw=1 "$1")"
bitrate="$(bc -l <<< "$size"/"$duration"*8.192)"
ffmpeg -i "$1" -c:v "$codec" -b:v "$bitrate"k "$2"
echo
echo "Duration: $duration seconds"
echo "Video stream size: $size KiB"
echo "Video bitrate: $bitrate kb/s"
echo "Video codec: $codec"
If you want additional parameters use ffprobe
to view a list of what's available:
ffprobe -loglevel error -show_streams input.mkv
Then use -select_entries
as shown in the script.
Note that codec_name
won't always match up with an encoder name, but usually it will Just Work. See ffmpeg -encoders
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With