diff options
-rwxr-xr-x | localless | 38 | ||||
-rwxr-xr-x | localpdf2pdfscreen | 88 | ||||
-rwxr-xr-x | localpdf2ps2pdf | 95 | ||||
-rwxr-xr-x | localvideowebencode | 41 |
4 files changed, 159 insertions, 103 deletions
diff --git a/localless b/localless new file mode 100755 index 0000000..773f7a5 --- /dev/null +++ b/localless @@ -0,0 +1,38 @@ +#!/bin/sh +# +# Copyright © 2021 Jonas Smedegaard <dr@jones.dk> +# Description: pipe a command to less with INT signal blocked +# +# This program is free software; +# you can redistribute it and/or modify it +# under the terms of the GNU General Public License +# as published by the Free Software Foundation; +# either version 2, or (at your option) any later version. +# +# Thanks to Jakub Wilk <jwilk@debian.org> for the trick +# +# Depends: less + +set -e + +PRG=$(basename "$0") + +showhelp() { + cat <<EOF +Usage: $PRG command [opetions...] + +Example: $PRG journalctl -ef +EOF +} + +exit1() { + echo "ERROR: $1" + exit 1 +} + +if [ $# -eq 0 ]; then + showhelp + exit1 "not enough parameters" +fi + +exec env --ignore-signal=INT "$@" | less diff --git a/localpdf2pdfscreen b/localpdf2pdfscreen deleted file mode 100755 index cd88a97..0000000 --- a/localpdf2pdfscreen +++ /dev/null @@ -1,88 +0,0 @@ -#!/bin/sh -# -# /usr/local/bin/localpdf2pdfscreen -# Copyright 2008 Jonas Smedegaard <dr@jones.dk> -# -# $Id: localpdf2pdfscreen,v 1.5 2008-03-17 13:39:17 jonas Exp $ -# -# Downsize PDF file. -# - -set -e - -PRG="$(basename "$0")" - -# Default options -PDFTOPSOPTS="-preload -paper match" -PS2PDFOPTS="-dPDFSETTINGS=/screen" - -showhelp() { - cat <<EOF -Usage: $PRG INFILE [ OUTFILE ] [ pdftops opts ] [ -- ps2pdf opts ] - -Defaults: - OUTFILE: INFILE with trailing ".pdf" replaced with "_lowres.pdf". - pdftops: $PDFTOPSOPTS - ps2pdfopts $PS2PDFOPTS - -Examples: - $PRG newspaper.pdf newspaper_screenready.pdf - $PRG newspaper.pdf -level3 -- - -EOF -} - -exit1() { - echo >&2 "ERROR: $1" - exit 1 -} - -[ $# -gt 0 ] || exit1 "Input file missing" - -infile= -outfile= -pdftopsopts= -pstopdfopts= -while [ $# -gt 0 ]; do - case $1 in - -h|--help) - showhelp - exit 0 - ;; - --) - shift - break - ;; - -*) - pdftopsopts="$pdftopsopts $1" - shift - ;; - *) - if [ -z "$infile" ]; then - infile="$1" - elif [ -z "$outfile" ]; then - outfile="$1" - else - exit1 "Too many parameters" - fi - shift - ;; - esac -done -ps2pdfopts="$@" - -# Use defaults if not overridden -outfile="${outfile:-$(basename "$infile" .pdf)_lowres.pdf}" -pdftopsopts="${pdftopsopts:-$PDFTOPSOPTS}" -ps2pdfopts="${ps2pdfopts:-$PS2PDFOPTS}" - -[ ! -e "$outfile" ] || exit1 "Output file already exists" - -tmpfile=$(mktemp -t "$PRG.XXXXXXXXXX") || exit 1 - -pdftops $pdftopsopts "$infile" "$tmpfile" || rm "$tmpfile" -ps2pdf $ps2pdfopts "$tmpfile" "$outfile" - -rm "$tmpfile" - -exit 0 diff --git a/localpdf2ps2pdf b/localpdf2ps2pdf new file mode 100755 index 0000000..7fe0a17 --- /dev/null +++ b/localpdf2ps2pdf @@ -0,0 +1,95 @@ +#!/bin/sh +# +# /usr/local/bin/localpdf2ps2pdf +# Copyright 2008-2023 Jonas Smedegaard <dr@jones.dk> +# +# Refry PDF file. +# + +set -e + +PRG="$(basename "$0")" + +# Default options +PDF2PSOPTS="" +PS2PDFOPTS="-dDownsampleColorImages=true -dColorImageResolution=150" + +showhelp() { + cat <<EOF +Usage: $PRG INFILE [ OUTFILE ] [ pdf2ps opts ] [ -- ps2pdf opts ] + +Defaults: + OUTFILE: INFILE with trailing ".pdf" replaced with "_lowres.pdf". + pdf2ps: $pdf2psOPTS + ps2pdf: $PS2PDFOPTS + +Examples: + $PRG file.pdf dFirstPage=7 -dLastPage=9 + $PRG file.pdf -- -dPDFA -dPDFACompatibilityPolicy=1 + $PRG file.pdf -- -dPDFSETTINGS=/screen + $PRG file.pdf -dLanguageLevel=3 -- -dPDFSETTINGS=/prepress + +First example above picks pages 7-9. +Second example above reduces PDF complexity. +Third example reduces image size for screen-only use. +Fourth example preserves complexity and image size for professional use. + +Defaults reduce file size for 300 DPI color print use. + +EOF +} + +exit1() { + echo >&2 "ERROR: $1" + exit 1 +} + +[ $# -gt 0 ] || exit1 "Input file missing" + +infile= +outfile= +pdf2psopts= +pstopdfopts= +while [ $# -gt 0 ]; do + case $1 in + -h|--help) + showhelp + exit 0 + ;; + --) + shift + break + ;; + -*) + pdf2psopts="$pdf2psopts $1" + shift + ;; + *) + if [ -z "$infile" ]; then + infile="$1" + elif [ -z "$outfile" ]; then + outfile="$1" + else + exit1 "Too many parameters" + fi + shift + ;; + esac +done +ps2pdfopts="$@" + +# Use defaults if not overridden +outfile="${outfile:-$(basename "$infile" .pdf)_lowres.pdf}" +pdf2psopts="${pdf2psopts:-$PDF2PSOPTS}" +ps2pdfopts="${ps2pdfopts:-$PS2PDFOPTS}" + +[ ! -e "$outfile" ] || exit1 "Output file already exists" + +tmpfile=$(mktemp -t "$PRG.XXXXXXXXXX") || exit 1 + +pdf2ps $pdf2psopts "$infile" "$tmpfile" || rm "$tmpfile" +ps2pdf $ps2pdfopts "$tmpfile" "$outfile" + +rm "$tmpfile" + +exit 0 diff --git a/localvideowebencode b/localvideowebencode index 0d6e00b..e1e5476 100755 --- a/localvideowebencode +++ b/localvideowebencode @@ -37,8 +37,6 @@ # * tune defaults # + adapt VP8/VP9 quantizer based on frame size # <https://developers.google.com/media/vp9/settings/vod#quality> -# + maybe pass option real_time=-2 to melt -# <https://www.reddit.com/r/kdenlive/comments/ka0aak/kdenlive_gpucpu_use_threads_mlt_and_ffmpeg_tips/> # + maybe reduce threads to "spend" total available cores only once # <https://blog.maxwellgale.com/2021/01/30/streaming-video-over-webrtc-using-ffmpeg/> # + apply application option when using opusenc @@ -87,6 +85,13 @@ # <https://github.com/gpac/gpac/commit/4529c60> # * support realtime streaming a.k.a. "ULL", i.e. less than 0.5s latency # <https://blog.maxwellgale.com/2021/01/30/streaming-video-over-webrtc-using-ffmpeg/> +# * adjust default loudness to AES TD1008 recommendations +# <https://www.aes.org/technical/documentDownloads.cfm?docID=729> +# <https://www.pro-tools-expert.com/production-expert-1/aes-update-loudness-recommendations-for-audio-only-streaming> +# * support non-melt loudness +# * ffmpeg -af loudnorm (since ffmpeg 3.1) +# <https://k.ylo.ph/2016/04/04/loudnorm.html> +# * ffmpeg -af dynaudnorm (since ffmpeg 2.8) set -e @@ -648,6 +653,12 @@ use_oggenc_any="${ogv:+$use_oggenc}${webm:+$use_oggenc}${webm_vp9:+$use_opusenc} [ -z "$gpu" ] || echo >&2 "GPU platform enabled: $gpu" +# cpu options +# TODO: maybe set real_time for multi-threading within melt itself (e.g. for filters) +_melt_consumer_avformat"-consumer threads=0 avformat" +#_melt_consumer_avformat="-consumer threads=0${processors:+ real_time=-$((processors-1))} avformat" +#_melt_consumer_avformat="-consumer threads=0${processors:+ real_time=-$((processors/2))} avformat" + # gpu options _melt_gpu_init=${gpu:+ ${gpu}_device=$gpudevice} _ffmpeg_gpu_vaapi_init="-${gpu}_device $gpudevice" @@ -738,7 +749,7 @@ _vpxenc_vp8="--codec=vp8$_vpxenc_bitrate_vp8 --end-usage=${no_q_vp8:+vbr}${q_vp8 _melt_vp9="vcodec=$encoder_vp9${pre_vp9:+ vpreset=$pre_vp9}${preset_vp9:+ preset=$preset_vp9}$_melt_bitrate_vp9${q_vp9:+ ${no_bitrate_vp9:+vb=0 }$qkey_vp9=$q_vp9}$_melt_misc_vp9" _ffmpeg_vp9="-c:v $encoder_vp9${pre_vp9:+ -vpre $pre_vp9}${preset_vp9:+ -preset $preset_vp9}$_ffmpeg_bitrate_vp9${q_vp9:+ ${no_bitrate_vp9:+-b:v 0 }-$qkey_vp9 $q_vp9}$_ffmpeg_misc_vp9" _vpxenc_vp9="--codec=vp9$_vpxenc_bitrate_vp9 --end-usage=${no_q_vp9:+vbr}${q_vp9:+cq --cq-level=$q_vp9}$_vpxenc_misc_vp9" -_melt_avc="vcodec=$encoder_avc${preset_avc:+ vpreset=$preset_avc}${profile_avc:+ vprofile=$profile_avc}${x264tune:+ tune=$x264tune}$_melt_bitrate_avc${q_avc:+ $qkey_avc=$q_avc} threads=0$_melt_misc_avc" +_melt_avc="vcodec=$encoder_avc${preset_avc:+ vpreset=$preset_avc}${profile_avc:+ vprofile=$profile_avc}${x264tune:+ tune=$x264tune}$_melt_bitrate_avc${q_avc:+ $qkey_avc=$q_avc}$_melt_misc_avc" _ffmpeg_avc="-c:v $encoder_avc${preset_avc:+ -preset $preset_avc}${profile_avc:+ -profile:v $profile_avc}${x264tune:+ -tune $x264tune}$_ffmpeg_bitrate_avc${q_avc:+ -$qkey_avc $q_avc}$_ffmpeg_misc_avc" _melt_pcm="$_melt_downmix acodec=pcm_s16le" _melt_vorbis="$_melt_downmix acodec=libvorbis aq=$quality_vorbis" @@ -753,7 +764,7 @@ _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" +_melt_stdout="$_melt_consumer_avformat:pipe:1 f=yuv4mpegpipe $_melt_video pix_fmt=yuv420p an=1 audio_off=1" _ffmpeg_stdin="-f yuv4mpegpipe -i pipe:0$_ffmpeg_gpu_filter" _ffmpeg_rawvideo="-f rawvideo" _melt_wav="f=wav $_melt_pcm vn=1 video_off=1" @@ -801,13 +812,13 @@ fi if [ -n "${ogv:+$multipass_theora}${webm:+$multipass_vp8}${webm_vp9:+$multipass_vp9}${mp4:+$multipass_avc}" ]; then echo >&2 "Analyzing video complexity..." render melt $_melt_infiles $filters \ - ${ogv:+${use_melt_theora:+-consumer avformat:$stem.ogv $_melt_ogv \ + ${ogv:+${use_melt_theora:+$_melt_consumer_avformat:$stem.ogv $_melt_ogv \ pass=1 passlogfile=${stem}_theora}} \ - ${webm:+${use_melt_vp8:+-consumer avformat:$stem.webm $_melt_webm \ + ${webm:+${use_melt_vp8:+$_melt_consumer_avformat:$stem.webm $_melt_webm \ pass=1 cpu-used=4 passlogfile=${stem}_vp8}} \ - ${webm_vp9:+${use_melt_vp9:+-consumer avformat:${stem}_vp9.webm $_melt_webm_vp9 \ + ${webm_vp9:+${use_melt_vp9:+$_melt_consumer_avformat:${stem}_vp9.webm $_melt_webm_vp9 \ pass=1 cpu-used=4 passlogfile=${stem}_vp9}} \ - ${mp4:+${use_melt_avc:+-consumer avformat:$stem.mp4 $_melt_mp4 \ + ${mp4:+${use_melt_avc:+$_melt_consumer_avformat:$stem.mp4 $_melt_mp4 \ pass=1 passlogfile=${stem}_avc}} \ ${use_any_nomelt_video:+$_melt_stdout} \ | pee \ @@ -832,17 +843,17 @@ render melt $_melt_infiles \ ${_melt_loudness:+-filter loudness program=$lufs \ results="$_melt_loudness"}} \ $filters${channels:+ $_melt_postfilters_audio} \ - ${ogv:+${use_melt_theora:+-consumer avformat:$stem.ogv $_melt_ogv \ + ${ogv:+${use_melt_theora:+$_melt_consumer_avformat:$stem.ogv $_melt_ogv \ ${multipass_theora:+pass=2 passlogfile=${stem}_theora}}} \ - ${webm:+${use_melt_vp8:+-consumer avformat:$stem.webm $_melt_webm \ + ${webm:+${use_melt_vp8:+$_melt_consumer_avformat:$stem.webm $_melt_webm \ ${multipass_vp8:+pass=2 passlogfile=${stem}_vp8}}} \ - ${webm_vp9:+${use_melt_vp9:+-consumer avformat:${stem}_vp9.webm $_melt_webm_vp9 \ + ${webm_vp9:+${use_melt_vp9:+$_melt_consumer_avformat:${stem}_vp9.webm $_melt_webm_vp9 \ ${multipass_vp9:+pass=2 passlogfile=${stem}_vp9}}} \ - ${mp4:+${use_melt_avc:+-consumer avformat:$stem.mp4 $_melt_mp4 + ${mp4:+${use_melt_avc:+$_melt_consumer_avformat:$stem.mp4 $_melt_mp4 ${multipass_avc:+pass=2 passlogfile=${stem}_avc}}} \ - ${channels:+${use_wav:+-consumer avformat:$stem.wav \ + ${channels:+${use_wav:+$_melt_consumer_avformat:$stem.wav \ $_melt_wav}} \ - ${channels:+${use_matroska:+-consumer avformat:$stem.mkv \ + ${channels:+${use_matroska:+$_melt_consumer_avformat:$stem.mkv \ $_melt_matroska_pcm}} \ ${use_any_nomelt_video:+$_melt_stdout} \ | pee \ @@ -923,7 +934,7 @@ rm -f $stem.xml $stem.wav $stem.mkv ${stem}_*.log ${stem}_*silent.webm # JPEG preview render melt $infile_first in=$stillframe out=$stillframe \ -group $filters \ - -consumer avformat:$stem.jpg $_melt_img + $_melt_consumer_avformat:$stem.jpg $_melt_img __width="${_width:+ width=\"$_width\"}" __height="${_height:+ height=\"$_height\"}" |