From a43ad7c880b41bff4cb7c6cd898d672cc50d7892 Mon Sep 17 00:00:00 2001 From: Jonas Smedegaard Date: Fri, 29 Jan 2021 08:14:04 +0100 Subject: support ffmpeg-based h.264 encoding --- localvideowebencode | 44 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/localvideowebencode b/localvideowebencode index 7f98157..d4d20c8 100755 --- a/localvideowebencode +++ b/localvideowebencode @@ -213,6 +213,7 @@ title=${title:-$stem} #use_ffmpeg_vp8=yes #use_ffmpeg_vp9=yes +#use_ffmpeg_h264=yes #use_vpxenc=yes # Avoid discrete audio encoders if possible: may cause sync problems #use_oggenc=yes @@ -477,6 +478,7 @@ for vformat in vp8 vp9 h264; do # melt supports dual-pass or Constant Quality modes only for h.264 [ h264 = "$vformat" ] || [ -n "$vpxenc" ] || eval "[ -z \"$multipass\$q_$vformat\" ] || use_ffmpeg_$vformat=yes" done +[ -n "$use_ffmpeg_h264" ] || use_melt_h264=yes if [ -n "$use_ffmpeg_vp8$use_ffmpeg_vp9$use_vpxenc" ]; then [ -n "$use_oggenc" ] || use_ffmpeg_ogg=yes [ -n "$use_opusenc" ] || use_ffmpeg_opus=yes @@ -530,6 +532,7 @@ _melt_vp9="vcodec=$encoder_vp9${pre_vp9:+ vpreset=$pre_vp9}${preset_vp9:+ preset _ffmpeg_vp9="-c:v $encoder_vp9${pre_vp9:+ -vpre $pre_vp9}${preset_vp9:+ -preset $preset_vp9}${bitrate_vp9:+ $_ffmpeg_bitrate_vp9}${q_vp9:+ ${no_bitrate_vp9:+-b:v 0 }-$qkey_vp9 $q_vp9}" _vpxenc_vp9="--codec=vp9${bitrate_vp9:+ $_vpxenc_bitrate_vp9} --end-usage=${no_q_vp9:+vbr}${q_vp9:+cq --cq-level=$q_vp9} $_vpxenc_misc_vp8" _melt_h264="vcodec=$encoder_h264${preset_h264:+ vpreset=$preset_h264}${profile_h264:+ vprofile=$profile_h264}${x264tune:+ tune=$x264tune}${bitrate_h264:+ maxrate=$bitrate_h264 bufsize=$((bitrate_h264*2))}${q_h264:+ $qkey_h264=$q_h264} threads=0 movflags=+faststart" +_ffmpeg_h264="-c:v $encoder_h264${preset_h264:+ -preset $preset_h264}${profile_h264:+ -profile:v $profile_h264}${x264tune:+ -tune $x264tune}${bitrate_h264:+ -maxrate $bitrate_h264 -bufsize $((bitrate_h264*2))}${q_h264:+ -$qkey_h264 $q_h264} -movflags +faststart" _melt_pcm="$_melt_downmix acodec=pcm_s16le" _melt_vorbis="$_melt_downmix acodec=libvorbis aq=$quality_vorbis" _ffmpeg_vorbis="$_ffmpeg_downmix -c:a libvorbis -aq $quality_vorbis" @@ -538,7 +541,9 @@ _melt_opus="$_melt_downmix acodec=libopus ab=$((channels*bitrate_opus))k${opusap _ffmpeg_opus="$_ffmpeg_downmix -c:a libopus -b:a $((channels*bitrate_opus))k${opusapp:+ -application $opusapp}" _opusenc_opus="$_opusenc_downmix --bitrate $((channels*bitrate_opus))" _melt_mp3="$_melt_downmix acodec=libmp3lame${use_lame_abr:+ aq=$quality_lame}${use_lame_cbr:+ ab=$((channels*bitrate_lame))k}" +_ffmpeg_mp3="$_ffmpeg_downmix -c:a libmp3lame${use_lame_abr:+ -q:a $quality_lame}${use_lame_cbr:+ -b:a $((channels*bitrate_lame))k}" _melt_aac="$_melt_downmix acodec=aac ab=$((channels*bitrate_aac))k" +_ffmpeg_aac="$_ffmpeg_downmix -c:a aac -b:a $((channels*bitrate_aac))k" # container options _melt_stdout="-consumer avformat:pipe:1 f=yuv4mpegpipe $_melt_video pix_fmt=yuv420p an=1 audio_off=1" @@ -564,6 +569,10 @@ _melt_webm_vp9="f=webm $_melt_video $_melt_vp9 ${silence:+an=1 audio_off=1}${cha _ffmpeg_webm_vp9="-f webm $_ffmpeg_video $_ffmpeg_vp9 ${silence:+-an}${channels:+$_ffmpeg_opus}" _ffmpeg_webm_onlyvideo_vp9="-f webm $_ffmpeg_video $_ffmpeg_vp9 -an" _melt_mp4="f=mp4 $_melt_video $_melt_h264 ${silence:+an=1 audio_off=1}${channels:+${use_mp3:+$_melt_mp3}${use_aac:+$_melt_aac}}" +_ffmpeg_mp4="-f mp4 $_ffmpeg_video $_ffmpeg_h264 ${silence:+-an}${channels:+${use_mp3:+$_ffmpeg_mp3}${use_aac:+$_ffmpeg_aac}}" +_ffmpeg_mp4_onlyvideo="-f mp4 $_ffmpeg_video $_ffmpeg_h264 -an" +_ffmpeg_mp4_keepvideo="-f mp4 $_ffmpeg_video -c:v copy ${silence:+-an}${channels:+$_ffmpeg_mp3}" +_ffmpeg_mp4_keepvideo_aac="-f mp4 $_ffmpeg_video -c:v copy ${silence:+-an}${channels:+$_ffmpeg_aac}" _melt_img="f=image2 $_melt_video" _melt_loudness="$loudness_data" @@ -578,7 +587,7 @@ if [ -n "$loudness" ] && [ -z "$silence$_melt_loudness" ]; then echo >&2 "Loudness data: $_melt_loudness" fi -if [ -n "$multipass" ] && [ -n "${webm:+$use_vpxenc$use_ffmpeg_vp8$use_oggenc}${vp9:+$use_vpxenc$use_ffmpeg_vp9$use_opusenc}" ]; then +if [ -n "$multipass" ] && [ -n "${webm:+$use_vpxenc$use_ffmpeg_vp8$use_oggenc}${vp9:+$use_vpxenc$use_ffmpeg_vp9$use_opusenc}${mp4:+$use_ffmpeg_h264}" ]; then echo >&2 "Analyzing video complexity..." if [ -n "$use_vpxenc" ]; then $melt $_melt_infiles $filters $_melt_stdout \ @@ -586,20 +595,26 @@ if [ -n "$multipass" ] && [ -n "${webm:+$use_vpxenc$use_ffmpeg_vp8$use_oggenc}${ ${webm:+"$vpxenc_chained - $_vpxenc_vp8 \ -p 2 --pass=1 --fpf=${stem}_vp8.log -o /dev/null"} \ ${vp9:+"$vpxenc_chained - $_vpxenc_vp9 \ - -p 2 --pass=1 --fpf=${stem}_vp9.log -o /dev/null"} + -p 2 --pass=1 --fpf=${stem}_vp9.log -o /dev/null"} \ + ${mp4:+${use_ffmpeg_h264:+$_ffmpeg_rawvideo $_ffmpeg_h264 -an \ + -pass 1 -passlogfile ${stem}_h264 /dev/null}} + [ -z "$mp4" ] || [ -n "$use_ffmpeg_h264" ] || mv -f ${stem}_h264-*.log ${stem}_h264_2pass.log else $melt $_melt_infiles $filters $_melt_stdout \ | $ffmpeg_chained $_ffmpeg_stdin \ ${webm:+$_ffmpeg_rawvideo $_ffmpeg_vp8 -an \ -pass 1 -passlogfile ${stem}_vp8 /dev/null} \ ${vp9:+$_ffmpeg_rawvideo $_ffmpeg_vp9 -an \ - -pass 1 -passlogfile ${stem}_vp9 /dev/null} + -pass 1 -passlogfile ${stem}_vp9 /dev/null} \ + ${mp4:+${use_ffmpeg_h264:+$_ffmpeg_rawvideo $_ffmpeg_h264 -an \ + -pass 1 -passlogfile ${stem}_h264 /dev/null}} [ -z "$webm" ] || [ -n "$use_ffmpeg_vp8" ] || mv -f ${stem}_vp8-*.log ${stem}_vp8_2pass.log [ -z "$vp9" ] || [ -n "$use_ffmpeg_vp9" ] || mv -f ${stem}_vp9-*.log ${stem}_vp9_2pass.log + [ -z "$mp4" ] || [ -n "$use_ffmpeg_h264" ] || mv -f ${stem}_h264-*.log ${stem}_h264_2pass.log fi fi -if [ -n "${webm:+$use_vpxenc$use_ffmpeg_vp8$use_oggenc}${vp9:+$use_vpxenc$use_ffmpeg_vp9$use_opusenc}" ]; then +if [ -n "${webm:+$use_vpxenc$use_ffmpeg_vp8$use_oggenc}${vp9:+$use_vpxenc$use_ffmpeg_vp9$use_opusenc}${mp4:+$use_ffmpeg_h264}" ]; then echo >&2 "Encoding video${channels:+ and extracting audio}, as discrete files..." $melt $_melt_infiles \ ${channels:+$audioprefilters \ @@ -607,7 +622,7 @@ if [ -n "${webm:+$use_vpxenc$use_ffmpeg_vp8$use_oggenc}${vp9:+$use_vpxenc$use_ff results="$_melt_loudness"}} \ $filters${channels:+ $_melt_postfilters_audio} \ ${ogg:+-consumer avformat:$stem.ogv $_melt_ogg} \ - ${mp4:+-consumer avformat:$stem.mp4 $_melt_mp4} \ + ${mp4:+${use_melt_h264:+-consumer avformat:$stem.mp4 $_melt_mp4}} \ ${channels:+${use_wav:+-consumer avformat:$stem.wav \ $_melt_wav}} \ ${channels:+${use_matroska:+-consumer avformat:$stem.mkv \ @@ -629,7 +644,11 @@ if [ -n "${webm:+$use_vpxenc$use_ffmpeg_vp8$use_oggenc}${vp9:+$use_vpxenc$use_ff ${vp9:+${use_vpxenc:+"$vpxenc_chained - $_vpxenc_vp9 \ ${singlepass:+-p 1} \ ${multipass:+-p 2 --pass=2 --fpf=${stem}_vp9.log} \ - -o ${stem}_vp9${channels:+_silent}.webm"}} + -o ${stem}_vp9${channels:+_silent}.webm"}} \ + ${mp4:+${use_ffmpeg_h264:+"$ffmpeg_chained \ + $_ffmpeg_stdin $_ffmpeg_mp4_onlyvideo \ + ${multipass:+-pass 2 -passlogfile ${stem}_h264} \ + ${stem}${channels:+_silent}.mp4"}} if [ -n "$webm" ] && [ -n "$channels" ]; then echo >&2 "Encoding Vorbis audio and muxing with VP8 video..." if [ -n "$use_oggenc" ]; then @@ -658,6 +677,19 @@ if [ -n "${webm:+$use_vpxenc$use_ffmpeg_vp8$use_oggenc}${vp9:+$use_vpxenc$use_ff $_ffmpeg_webm_keepvideo_opus ${stem}_vp9.webm fi fi + if [ -n "${mp4:+$use_ffmpeg_h264}" ] && [ -n "$channels" ]; then + if [ -n "$use_mp3" ]; then + echo "Encoding MP3 audio and muxing with h.264 video..." + $ffmpeg_alone $_ffmpeg_mp4_in -i ${stem}_silent.mp4 \ + $_ffmpeg_matroska_wav_in -i $stem.mkv \ + $_ffmpeg_mp4_keepvideo ${stem}.mp4 + else + echo "Encoding AAC audio and muxing with h.264 video..." + $ffmpeg_alone $_ffmpeg_mp4_in -i ${stem}_silent.mp4 \ + $_ffmpeg_matroska_wav_in -i $stem.mkv \ + $_ffmpeg_mp4_keepvideo_aac ${stem}.mp4 + fi + fi else echo >&2 "Encoding video${channels:+ and audio}, at once..." $melt $_melt_infiles \ -- cgit v1.2.3