我有一个用于剪切/修剪媒体文件的脚本 - 初始详细信息这里和这里;经过最近的一些调整调整它看起来像这样:
#!/bin/bash
INPUT=$1
eval $(yad --width=400 --form --field=start --field=end --field=output:SFL "00:00:00" "00:00:00" "${INPUT/%.*}-out.${INPUT##*.}" | awk -F'|' '{printf "START=%s\nEND=%s\nOUTPUT=\"%s\"\n", $1, $2, $3}')
[[ -z $START || -z $END || -z $OUTPUT ]] && exit 1
DIFF=$(($(date +%s --date="$END")-$(date +%s --date="$START")))
OFFSET=""$(($DIFF / 3600)):$(($DIFF / 60 % 60)):$(($DIFF % 60))
$(ffmpeg -ss "$START" -t "$OFFSET" -i "$INPUT" -c copy "$OUTPUT")
(for i in $(seq 0 3 100); do echo "$i"; sleep 0.1; done) | zenity --progress --width=400 --auto-close
if [ $? -eq 0 ]; then
kdialog --msgbox "Process completed successfully!"
else
kdialog --msgbox "SOMETHING WENT WRONG!"
fi
它包含一行来显示 zenity 中 ffmpeg 进程的进度。
~$ zenity --help-progress
Usage:
zenity [OPTION…]
Progress options
--progress Display progress indication dialog
--text=TEXT Set the dialog text
--percentage=PERCENTAGE Set initial percentage
--pulsate Pulsate progress bar
--auto-close Dismiss the dialog when 100% has been reached
--auto-kill Kill parent process if Cancel button is pressed
--no-cancel Hide Cancel button
--time-remaining Estimate when progress will reach 100%
但仅仅使用并zenity --progress --percentage=1
不能显示真正的进展,唯一有用的选项似乎是使用--pulsate
,它至少显示了来回移动的线条正在发生的事情。
ffmpeg -ss "$START" -t "$OFFSET" -i "$INPUT" -c copy "$OUTPUT" | zenity --width=400 --progress --pulsate --text="Running" --percentage=1 --auto-close --auto-kill
尝试模仿这回答我确实得到了一个进度条,但是显示的是后过程已经结束,进展本身与真实过程无关。
$(ffmpeg -ss "$START" -t "$OFFSET" -i "$INPUT" -c copy "$OUTPUT")
(for i in $(seq 0 3 100); do echo "$i"; sleep 0.1; done) | zenity --progress --width=400
当我尝试使用类似这,脚本调整如下
#!/bin/bash
(
INPUT=$(kdialog --getopenfilename ~/Videos/ '*.m4a *.ogg *.mp3 *.mp4 *.avi *.aac *.flac *.avi *.mkv *.mp4')
echo "5"
eval $(yad --width=400 --form --field=start --field=end --field=output:SFL "00:00:00" "00:00:00" "${INPUT/%.*}-out.${INPUT##*.}" | awk -F'|' '{printf "START=%s\nEND=%s\nOUTPUT=\"%s\"\n", $1, $2, $3}')
[[ -z $START || -z $END || -z $OUTPUT ]] && exit 1
DIFF=$(($(date +%s --date="$END")-$(date +%s --date="$START")))
echo "5"
OFFSET=""$(($DIFF / 3600)):$(($DIFF / 60 % 60)):$(($DIFF % 60))
echo "10"
echo "# Running processing task." ; sleep 1
echo "35"
echo "# Running processing task." ; sleep 1
echo "60"
echo "# Running processing task." ; sleep 1
echo "85"
echo "# Running processing task." ; sleep 1
echo "99"
echo "# Running processing task." ; sleep 1
ffmpeg -ss "$START" -t "$OFFSET" -i "$INPUT" -c copy "$OUTPUT"
echo "# All finished." ; sleep 1
echo "100"
我得到了一个进度条,但是进度条显示前实际过程已经发生。
问题是:
如何实现如上图所示的效果,但又与实际过程实时同步ffmpeg
?
答案1
我只ffmpeg
在需要时才使用,就我的经验而言,这就是全部,所以对这部分持保留态度...因此,我研究了它并注意到一些看起来像的输出time=00:00:00:0.0
,并发现它可以用于你的目的。
这会很难看...但是,可以将其视为一个模板或样板。
使用您的$DIFF
(只需几秒即可完成,130
例如不是采用全时格式,例如00:02:10
) 变量(仅限进度条)
ffmpeg -ss "$START" -t "$OFFSET" -i "$INPUT" -c copy "$OUTPUT" 2>&1 |
grep --line-buffered -Po "(?<=time=)[0-9:.]*" |
while read -r line; do echo "$line" |
awk -v offset="$DIFF" -F: 't=($1 * 3600) + ($2 * 60) + $3 {print t / offset * 100}'; done |
zenity --progress
...还有文本输出
ffmpeg -ss "$START" -t "$OFFSET" -i "$INPUT" -c copy "$OUTPUT" 2>&1 |
while read -r line; do grep -Po "(?<=time=)[0-9:.]*" <<<"$line" |
awk -v offset="$DIFF" -F: 't=($1 * 3600) + ($2 * 60) + $3 {print t / offset * 100}'; echo "# $line"; done |
zenity --progress --width="500"
更多相关解释可以在这里找到:https://askubuntu.com/a/1477618
另外,上面的两个例子使用了它们,它们应该可以与或zenity
一起使用,但是你不应该将它们混合在一起(在执行同一项任务时),并且你不需要这里使用的“没有安全开关的枪”,你也不想要它...要知道这有多糟糕,请在终端中尝试在脚本中执行的操作,如下所示:kdialog
yad
eval
eval $(yad --width=400 --form --field=start --field=end --field=output:SFL "00:00:00" "00:00:00" "${INPUT/%.*}-out.${INPUT##*.}" | awk -F'|' '{printf "START=%s\nEND=%s\nOUTPUT=\"%s\"\n", $1, $2, $3}')
...并在第一个字段中输入以下内容:
; for f in "$HOME"/*/*; do echo "Removing $f"; done;
...然后单击“确定”...
我敢打赌你不喜欢它...它是无害的,因为我是一个好人:-)但你可以想象一个坏人会做什么,你就会明白。
但是你可以做这样的事情:
#!/bin/bash
INPUT="$1"
readarray -d "|" -t selection < <(yad --width=400 --form --field="start" --field="end" \
--field="output":SFL "00:00:00" "00:00:00" "${INPUT/%.*}-out.${INPUT##*.}")
[[ -z "${selection[0]}" || -z "${selection[1]}" || -z "${selection[2]}" ]] && exit 1
DIFF=$(($(date +%s --date="${selection[1]}")-$(date +%s --date="${selection[0]}")))
OFFSET=""$(($DIFF / 3600)):$(($DIFF / 60 % 60)):$(($DIFF % 60))
ffmpeg -nostdin -loglevel trace -ss "${selection[0]}" -t "$OFFSET" -i "$INPUT" -c copy "${selection[2]}" 2>&1 |
grep --line-buffered -Po "(?<=time=)[0-9:.]*" |
while read -r line; do echo "$line" |
awk -v offset="$DIFF" -F: 't=($1 * 3600) + ($2 * 60) + $3 {print t / offset * 100}'; done |
zenity --progress --width="600" \
--text="Cropping file: (${INPUT})\nFrom (time): (${selection[0]})\nTo (time): (${selection[1]})\nFor (seconds): (${DIFF})\nOutput file: (${selection[2]})" \
--time-remaining
技术通告 ffmpeg
似乎对上述输出采取了不同的行动,即time=00:00:00:0.0
它似乎以某种交互式(自动更新)形式打印,并且一直保留到输出通过管道传输的过程结束...但是,当有其他打印消息(警告、信息、错误......等)时,它似乎会立即通过管道发送,因为这些消息似乎会强制刷新标准流缓冲区......因此,增加到-loglevel
似乎trace
可以解决问题并强制实时状态栏...但是,如果您还想在窗口中显示输出,则需要进行调整,zenity
因为您需要进行一些消息过滤(这些跟踪消息包含各种输出,包括数字,这会扰乱状态栏的准确性)。