我将扩展名为.srt,.ass,.ssa,.txt的文件(非递归)放在以下文件中:
my @subfiles = glob '*.srt *.txt *.ass *.ssa';
然后,为我调用的spumux编写xml子文件:
WRITESUBXML();
如下:
sub WRITESUBXML {
foreach my $i (@subfiles) {
$SUBXMl="/users/dragonzero29/.wine/drive_c/mvtmp/$subfiles[$i].xml";
open(my $fh, '>', $SUBXMl) or die "Could not open file $SUBXMl $!";
print $fh "<subpictures format=\"NTSC\">\n";
print $fh "<stream>\n";
print $fh "<textsub filename=\"$subfiles[$i]\"\n";
print $fh "characterset=\"UTF-8\"\n";
print $fh "fontsize=\"28.0\"\n";
print $fh "font=\"/users/dragonzero29/.wine/drive_c/mvtmp/arial.ttf\"\n";
print $fh "fill-color=\"yellow\"\n";
print $fh "outline-color=\"LightGray\"\n";
print $fh "outline-thickness=\"2.0\"\n";
print $fh "horizontal-alignment=\"center\"\n";
print $fh "vertical-alignment=\"bottom\"\n";
print $fh "left-margin=\"60\"\n";
print $fh "right-margin=\"60\"\n";
print $fh "top-margin=\"20\"\n";
print $fh "bottom-margin=\"30\"\n";
print $fh "subtitle-fps=\"29.97\"\n";
print $fh "movie-fps=\"29.97\"\n";
print $fh "movie-width=\"720\"\n";
print $fh "movie-height=\"480\"\n";
print $fh "force=\"no\"/>\n";
print $fh "</stream>\n";
print $fh "</subpictures>";
close($fh);
}
}
然后,稍后我调用该函数以写入最终的dvdauthor文件
WRITEAUTHORXML();
,其中包含:
sub WRITEAUTHORXML {
$AUTHORFILe="/users/dragonzero29/.wine/drive_c/mvtmp/authormovie.xml";
open(my $fh, '>', $AUTHORFILe) or die "Could not open file $AUTHORFILe $!";
print $fh "<dvdauthor dest=\"/users/dragonzero29/.wine/drive_c/mvtmp/DVD\">\n";
print $fh "<vmgm />\n";
print $fh "<titleset>\n";
print $fh "<menus>\n";
print $fh "<pgc>\n";
print $fh "<button> jump title 1\; </button>\n";
print $fh "<vob file=\"/users/dragonzero29/.wine/drive_c/mvtmp/menu.mpg\" pause=\"inf\"/>\n";
print $fh "</pgc>\n";
print $fh "</menus>\n";
print $fh "<titles>\n";
foreach my $LANg = grep(/^EN/ || /^ES/,@subfiles) {
print $fh "<subpicture lang=\"$LANg\"\n";
}
print $fh "<pgc>\n";
print $fh "<vob file=\"/users/dragonzero29/.wine/drive_c/mvtmp/$MOVIe.MUXED.MPG\"
print $fh "<post>\n";
print $fh "call menu\;\n";
print $fh "</post>\n";
print $fh "</pgc>\n";
print $fh "</titles>\n";
print $fh "</titleset>\n";
print $fh "</dvdauthor>\n";
close($fh);
return 0;
}
运行时会吐出:
syntax error at /users/dragonzero29/cm2dvd_v2.pl line 309, near "$LANg ="
Global symbol "$fh" requires explicit package name (did you forget to declare "my $fh"?) at /users/dragonzero29/cm2dvd_v2.pl line 312.
Global symbol "$fh" requires explicit package name (did you forget to declare "my $fh"?) at /users/dragonzero29/cm2dvd_v2.pl line 313.
Global symbol "$fh" requires explicit package name (did you forget to declare "my $fh"?) at /users/dragonzero29/cm2dvd_v2.pl line 314.
Global symbol "$fh" requires explicit package name (did you forget to declare "my $fh"?) at /users/dragonzero29/cm2dvd_v2.pl line 315.
Global symbol "$fh" requires explicit package name (did you forget to declare "my $fh"?) at /users/dragonzero29/cm2dvd_v2.pl line 316.
Global symbol "$fh" requires explicit package name (did you forget to declare "my $fh"?) at /users/dragonzero29/cm2dvd_v2.pl line 317.
Global symbol "$fh" requires explicit package name (did you forget to declare "my $fh"?) at /users/dragonzero29/cm2dvd_v2.pl line 318.
Global symbol "$fh" requires explicit package name (did you forget to declare "my $fh"?) at /users/dragonzero29/cm2dvd_v2.pl line 319.
Global symbol "$fh" requires explicit package name (did you forget to declare "my $fh"?) at /users/dragonzero29/cm2dvd_v2.pl line 320.
Global symbol "$fh" requires explicit package name (did you forget to declare "my $fh"?) at /users/dragonzero29/cm2dvd_v2.pl line 321.
syntax error at /users/dragonzero29/cm2dvd_v2.pl line 323, near "}"
/users/dragonzero29/cm2dvd_v2.pl has too many errors.
好吧,编辑使我成功地编译了脚本,并且dvd项目脚本一直可以进行iso创建,但是我注意到甚至没有创建字幕xml文件,因此最终的dvd没有字幕... aargh :(请帮助。这也是用于生成xml文件的代码,与上面的代码一起使用
foreach my $i(0 .. $#subxmlfiles) {
system("spumux -s0 -m dvd -P
\"/users/dragonzero29/.wine/drive_c/mvtmp/$subxmlfiles[$i]\" <
\"/users/dragonzero29/.wine/drive_c/mvtmp/$MOVIe.MUXED.MPG\" >
\"/users/dragonzero29/.wine/drive_c/mvtmp/$MOVIe.MUXED.MPG\"\n\n");
}
对不起,我仍然不明白如何从TextMate放置代码 请告知这个空间。
答案 0 :(得分:3)
如果存在语法错误,请忽略所有其他错误并首先处理该语法错误。
语法错误通常会使perl混淆您所处的范围;在这里,它无法解析错误的foreach my $LANg
,但确实看到了}
并认为它结束了子。因此,其后的所有内容都没有词汇$fh
。
答案 1 :(得分:2)
这部分在语法上不正确:
foreach my $LANg = grep(/^EN/ || /^ES/,@subfiles) {
print $fh "<subpicture lang=\"$LANg\"\n";
}
您至少需要将其重写为:
foreach my $LANg (grep(/^EN/ || /^ES/,@subfiles)) {
print $fh "<subpicture lang=\"$LANg\"\n";
}
但我建议改为:
foreach my $lang (grep { /^(?:EN|ES)/ } @subfiles) {
print $fh "<subpicture lang=\"$lang\"\n";
}
请注意,如果@subfiles
是文件名列表,则grep可能不会按照您的期望执行逻辑操作,grep将返回以EN
或ES
开头的文件名(是它们是这样命名的吗?您需要考虑路径中是否包含目录),然后返回整个文件名(不只是匹配的文件名)在$lang
中。因此,$lang
绝不会只是EN
或ES
而是整个文件名。如果您只需要提取名称的一部分,可以照看map
,它通常是grep
的好伴侣。
正如@Borodin在注释中指出的那样,您在代码中还有其他各种问题,例如$i
中的foreach my $i (@subfiles)
变量不是索引(0、1、2等),而是您要使用@subfiles
迭代到foreach
的一个元素,即文件名,因此$subnames[$i]
将是运行时错误,因为$i
不是索引(数字值)。
因此,请确保在脚本之上添加use strict; use warnings;
并调试语法,然后调试运行时错误。
您还可以进行许多其他常规改进。
例如,在https://perldoc.perl.org/perlop.html#Quote-Like-Operators中搜索“ <<EOF
”,看看“ here-documents”。
这将允许您替换例如:
print $fh "<vmgm />\n";
print $fh "<titleset>\n";
print $fh "<menus>\n";
print $fh "<pgc>\n";
通过:
print $fh <<'EOF';
<vmgm />
<titleset>
<menus>
<pgc>
EOF
这将大大简化代码,因为您无需在其中转义"
。
更多想法:
$i
甚至$LANg
:第一个变量没有任何语义值,第二个变量应为$lang
,因为混合大小写容易出错&
,<
和>
,否则XML无效?使用图书馆为您做到这一点。