ffmpeg/avconv: transcode using same codec and params as input

后端 未结 2 951
终归单人心
终归单人心 2021-01-18 19:41

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 somet

相关标签:
2条回答
  • 2021-01-18 20:11

    This seems to work

    file="input.mp4"
    ffmpeg -re -y -i "$file"  -c:v `ffprobe $file |& grep 'Video:' | awk -v N=4 '{print $N}'`  -b:v `ffprobe $file |& grep 'Video:' | awk -v N=15 '{print $N}'`k -f flv output.mp4
    

    The key here is this part, which grabs the video codec from the input file. You'll notice this appears twice in the statement, the second time it grabs the bitrate.

    `ffprobe $file |& grep 'Video:' | awk -v N=4 '{print $N}'`
    
    0 讨论(0)
  • 2021-01-18 20:35

    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.

    0 讨论(0)
提交回复
热议问题