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
相关产品推荐
相关产品推荐

