在 bash 脚本里用 find 命令和管道自动把文件名导入 ffmpeg 的 input 的时候,总有不完整或者错误的路径被导入 input,求大佬们帮忙看下问题

2022-01-13 15:06:07 +08:00
 SCGabriel
#!/bin/bash
clear
read -p "请输入视频格式后缀[比如 mkv 或者 mp4]:"
videotype=$REPLY
read -p "请输入字幕格式后缀[比如 ass 或者 srt]:"
subtype=$REPLY
read -p "请输入字幕信息[比如制作字幕的字幕组或者语言信息,示例 白月字幕组简体中文(Simplified Chinese) ]:"
subinfo=$REPLY
read -p "请输入输出文件夹路径[输出文件夹路径请不要设置成当前文件夹或者当前文件夹的子文件夹]:"
outputtotaldir=$REPLY
find . -type d -exec mkdir -p $outputtotaldir/\{\} \; # 在输出文件夹建立与当前文件夹内一模一样的目录结构
find . -type f -name "*.$videotype" -print0 | while read -r -d "" video # 查找所有.mkv 的视频文件并逐个将文件名写入$video 参数
do
	prevideo="${video#*/}" # 去掉$video 路径里面最左边的 /以及 /左边的字符
	subtitle="$(echo "$video" | sed "s/.$videotype$/.$subtype/")" # 用 sed 命令将$line 参数里"xxx xxx.mkv"的文件名转换成 jpg 结尾"xxx xxx.ass"
	output="$outputtotaldir/$(echo "$prevideo" | sed "s/.$videotype$/[chs\&eng].mkv/")"
	ffmpeg -i "$video" -i "$subtitle" -map 0:v -map 0:a -map 1:s -metadata:s:s:0 language="$subinfo" -metadata:s:s:0 title="$subinfo" -c copy "$output"
done

自己写的一个简单 bash 脚本,就是想批量处理下视频省点力气。结果不知道为什么,这个脚本对零星几个视频文件执行起来一点错误也没有。但是视频数量一多,比如这批正在处理的 100 多个视频文件,就会时不时跳出来错误。

而且错误原因全是 ffmpeg 的 input 被输入了不存在的文件路径,咱认为是管道传递过去的文件路径缺失不完整,但是完全不知道是什么原因,也不知道怎么修。。。报错的截图如下,求大佬们帮忙看下 https://s2.loli.net/2022/01/13/M58vsOBHWP6eSQI.jpg https://s2.loli.net/2022/01/13/xgZ6RwYmTSyvbQH.png https://s2.loli.net/2022/01/13/oKNkR1y3eGXnOLT.png

966 次点击
所在节点    问与答
9 条回复
rationa1cuzz
2022-01-13 15:59:31 +08:00
没仔细看,把命令都打印出来,手动执行一遍看什么问题?
mxT52CRuqR6o5
2022-01-13 16:09:54 +08:00
确定和数量有关系吗?你给的报错的那几个文件单独处理是没问题吗?
pcmid
2022-01-13 16:56:24 +08:00
set -x 看看
SCGabriel
2022-01-13 17:05:56 +08:00
GeruzoniAnsasu
2022-01-13 17:08:21 +08:00
你这脚本里双引号套双引号了真的没问题吗……
「输入了不存在的路径」 第一反应是有空格捣乱
SCGabriel
2022-01-13 17:08:37 +08:00
@rationa1cuzz @mxT52CRuqR6o5 @pcmid
报错的单独执行都没问题,刚刚群里有人出手帮忙看了下,其实是循环有问题,改了下就好了。
咱萌新,就硬把一些代码拼凑在一起所以出错了,咱把改的贴出来算了

```bash
#!/bin/bash
clear
read -p "请输入视频格式后缀[比如 mkv 或者 mp4]:"
videotype=$REPLY
read -p "请输入字幕格式后缀[比如 ass 或者 srt]:"
subtype=$REPLY
read -p "请输入字幕信息[比如制作字幕的字幕组或者语言信息,示例 白月字幕组简体中文(Simplified Chinese) ]:"
subinfo=$REPLY
read -p "请输入输出文件夹路径[输出文件夹路径请不要设置成当前文件夹或者当前文件夹的子文件夹]:"
outputtotaldir=$REPLY
find . -type d -exec mkdir -p $outputtotaldir/\{\} \; # 在输出文件夹建立与当前文件夹内一模一样的目录结构
IFS_BAK=$IFS
IFS=$'\n'
for video in `find . -type f -name "*.$videotype"` # 查找所有.mkv 的视频文件并逐个将文件名写入$video 参数
do
prevideo="${video#*/}" # 去掉$video 路径里面最左边的 /以及 /左边的字符
subtitle="$(echo "$video" | sed "s/.$videotype$/.$subtype/")" # 用 sed 命令将$line 参数里"xxx xxx.mkv"的文件名转换成 jpg 结尾"xxx xxx.ass"
output="$outputtotaldir/$(echo "$prevideo" | sed "s/.$videotype$/[chs\&eng].mkv/")" # 用 sed 命令将$line 参数里"xxx xxx.mkv"的文件名转换成 jpg 结尾"xxx xxx[chs&eng].mkv"
ffmpeg -i "$video" -i "$subtitle" -map 0:v -map 0:a -map 1:s -metadata:s:s:0 language="$subinfo" -metadata:s:s:0 title="$subinfo" -c copy "$output"
done
IFS=$IFS_BAK
```
SCGabriel
2022-01-13 17:09:59 +08:00
@GeruzoniAnsasu 实际这个反而没有问题,ffmpeg 支持整个路径用双引号括起来输入,是咱循环有问题,群里有人帮改了下就行了,改过的贴上面了
amrnxcdt
2022-01-13 17:12:46 +08:00
应该是一些文件名含有特殊符号(比如空格或者斜杠)被 shell 转义了,当成是参数传入了 ffmpeg 。
SCGabriel
2022-01-13 17:18:33 +08:00
@amrnxcdt 转义的问题咱昨天遇到了,但这个问题确实不是转义的问题。有人出手帮咱修正了,已经解决了,也谢谢您

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/828020

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX