You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

YouTube视频毫秒级片段下载的Bash脚本问题排查与解决

YouTube视频毫秒级片段截取脚本问题及解决

我使用如下Bash脚本下载长YouTube视频的短片段:

#!/bin/bash
#taken from https://unix.stackexchange.com/a/388148/48971

if [ $# -lt 4 ]; then
        echo "Usage: $0 <youtube's URL> <HH:mm:ss.milisecs from time> <HH:mm:ss.milisecs to time> <output_file_name>"
        echo "e.g.:"
        echo "$0 https://www.youtube.com/watch?v=T1n5gXIPyws 00:00:25 00:00:42 intro.mp4"
        exit 1
fi

echo "processing..."

from=$(date "+%s" -d "UTC 01/01/1970 $2")
to=$(date "+%s" -d "UTC 01/01/1970 $3")

from_pre=$(($from - 30))

if [ $from_pre -lt 0 ]
then
        from_pre=0
fi

from_pre_command_print=$(date -u "+%T" -d @$from_pre)
from_command_print=$(date -u "+%T" -d @$(($from - $from_pre)))$(grep -o "\..*" <<< $2)
to_command_print=$(date -u "+%T" -d @$(($to - $from_pre)))$(grep -o "\..*" <<< $3)

command="ffmpeg "

for uri in $(youtube-dl -g $1)
do
        command+="-ss $from_pre_command_print -i $uri "
done

command+="-ss $from_command_print -to $to_command_print $4"
echo "downloading with the following command:"
echo "$command" 
$command

但该脚本的精度仅为整秒,我需要批量下载大量长度大多不足1秒的单字发音片段,无法满足需求。

我尝试通过date命令获取毫秒级时间戳解决该问题,但发现Bash仅支持整数运算,我的尝试方案如下:

from=$(date "+%s.%3N" -d "UTC 01/01/1970 $2")
to=$(date "+%s.%3N" -d "UTC 01/01/1970 $3")

function diff {
    diff="$(echo $from - 5 | bc)"
    echo $diff
}
from_pre=$diff
echo $diff

但借助bc实现浮点数运算的方案不可行,后续脚本执行时会因Bash无法处理非整数抛出错误。

示例执行命令如下:

sh download_youtube.sh https://www.youtube.com/watch?v=dH3auOKyxio 00:06:28.230 00:06:28.740 clip004.mp4

该命令仅在时间窗口大于1秒时可正常运行,我目前没有思路实现更高精度的截取。该功能是从YouTube频道自动剪辑特定词语生成拼接视频项目的一部分,恳请各位提供帮助。


更新

经过反复试错,我发现如下修改后的脚本可满足需求:

#!/bin/bash
#taken from https://unix.stackexchange.com/a/388148/48971

if [ $# -lt 4 ]; then
        echo "Usage: $0 <youtube's URL> <HH:mm:ss.milisecs from time> <HH:mm:ss.milisecs to time> <output_file_name>"
        echo "e.g.:"
        echo "$0 https://www.youtube.com/watch?v=T1n5gXIPyws 00:00:25 00:00:42 intro.mp4"
        exit 1
fi

echo "processing..."

from=$(date "+%s" -d "UTC 01/01/1970 $2")
to=$(date "+%s" -d "UTC 01/01/1970 $3")

from_pre=$(($from - 20))
#to_post=$(($to + 20))

if [ $from_pre -lt 0 ]
then
        from_pre=0
fi

from_pre_command_print=$(date -u "+%T" -d @$from_pre)

from_command_print=$(date -u "+%T" -d @$(($from - $from_pre)))$(grep -o "\..*" <<< $2)

to_command_print=$(date -u "+%T" -d @$(($to - $from_pre)))$(grep -o "\..*" <<< $3)

#to_post_command_print=$(date -u "+%T.%3N" -d @$to_post)

command="ffmpeg "

for uri in $(youtube-dl -g $1)
do
        command+="-ss $from_pre_command_print -i $uri "
done

command+="-ss $from_command_print -to $to_command_print $4"
echo "downloading with the following command:"
echo "$command" 
$command

后来我发现原脚本实际上本身就支持毫秒级精度,单独执行如下命令是正常的:

sh download_youtube.sh https://www.youtube.com/watch?v=dH3auOKyxio 00:06:28.230 00:06:28.740 clip004.mp4

但和批量逐行读取文本文件参数执行命令的脚本配合使用时,毫秒级参数会失效。


问题已解决

原脚本本身无问题,仅不识别时间戳中的逗号分隔符,将逗号替换为点号后即可正常实现毫秒级精度截取。


内容的提问来源于stack exchange,提问作者ArchDoge

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 10:15:09