Board logo

标题: [文本处理] [已解决]批处理把srt字幕显示持续时间缩短 [打印本页]

作者: vwfgh    时间: 2022-8-31 14:02     标题: [已解决]批处理把srt字幕显示持续时间缩短

本帖最后由 vwfgh 于 2022-9-1 08:00 编辑

我有这样的双语字幕,每句字幕的结束时间是下一句字幕的开始时间,但是有时候两句话之间相隔很长时间,那上一句话的字幕就会一直显示。

我想改成,如果两句字幕相隔时间小于5秒,那就按原来的方案处理。如果大于5秒,那上一句字幕的持续时间就改成5秒,请问这种能用脚本实现吗?

下面是字幕例子。

1
00:00:06,058 --> 00:00:07,578
안녕하세.
你好。

2
00:00:07,578 --> 00:00:10,938
여러분.
各位。

3
00:00:10,938 --> 00:00:12,238
안녕하세요.
你好。
作者: idwma    时间: 2022-8-31 17:46

  1. #@&cls&powershell "type '%~0'|out-string|iex"&pause&exit
  2. $srt='字幕.srt'
  3. $s=[timespan]::FromSeconds(5)
  4. sc -enc utf8 $srt $(
  5.     type $srt|%{
  6.         if($_ -match '-->'){
  7.             $a=$_ -replace ',','.' -split '\s+-->\s+'
  8.             $f=[datetime]$a[0]
  9.             $l=[datetime]$a[1]
  10.             if($l-$f -gt $s){'{0:HH:mm:ss,fff} --> {1:HH:mm:ss,fff}' -f $f,($f+$s)}else{$_}
  11.         }else{$_}
  12.     }
  13. )
复制代码

作者: vwfgh    时间: 2022-8-31 19:13

运行出错了
作者: vwfgh    时间: 2022-8-31 19:14

回复 2# idwma


大佬 我运行后提示:
type : 找不到路径“H:\test\瀛楀箷.srt”,因为该路径不存在。
所在位置 行:5 字符: 5
+     type $srt|%{
+     ~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (H:\test\瀛楀箷.srt:String) [Get-Content], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand

请按任意键继续. . .

然后出现个 瀛楀箷.srt 的空白文档,不知道哪错了?
作者: idwma    时间: 2022-8-31 20:11

回复 4# vwfgh


    复现不了你的情况,不知道呀
作者: fzp070    时间: 2022-8-31 20:13

本帖最后由 fzp070 于 2022-8-31 20:21 编辑

回复 4# vwfgh

这个乱码,感觉是编码格式的问题啊,将bat文件保存为ANSI编码格式,字幕文件也是ANSI编码。
如果保存为UTF-8的编码,那就在代码最前面加上 chcp 65001>nul,试试看
作者: vwfgh    时间: 2022-8-31 20:15

回复 6# fzp070


保存完ansi后显示:

type : 找不到路径“H:\test\字幕.srt”,因为该路径不存在。
所在位置 行:5 字符: 5
+     type $srt|%{
+     ~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (H:\test\字幕.srt:String) [Get-Content], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand
作者: vwfgh    时间: 2022-8-31 20:17

保存完ansi后,执行两次脚本不提示错误了,但是生成的文件还是空白。
作者: fzp070    时间: 2022-8-31 20:18

本帖最后由 fzp070 于 2022-8-31 20:20 编辑

回复 7# vwfgh
回复 5# idwma

powershell我不懂,得2楼大佬idwma帮忙解答
作者: vwfgh    时间: 2022-8-31 20:28

回复 9# fzp070


谢谢帮助
作者: idwma    时间: 2022-8-31 20:39

  1. #@&cls&powershell "type '%~0'|out-string|iex"&pause&exit
  2. $s=[timespan]::FromSeconds(5)
  3. dir *.srt|%{
  4. $srt=$_.fullname
  5. sc -enc utf8 $srt $(
  6.     type $srt|%{
  7.         if($_ -match '-->'){
  8.             $a=$_ -replace ',','.' -split '\s+-->\s+'
  9.             $f=[datetime]$a[0]
  10.             $l=[datetime]$a[1]
  11.             if($l-$f -gt $s){'{0:HH:mm:ss,fff} --> {1:HH:mm:ss,fff}' -f $f,($f+$s)}else{$_}
  12.         }else{$_}
  13.     }
  14. )
  15. }
复制代码

作者: vwfgh    时间: 2022-8-31 21:05

回复 11# idwma


谢谢大佬!辛苦了!这次可以了。

但是我发现个奇怪的bug,当文件名里有 [ 这个符号时,脚本就会无法执行,提示:

标题中只有[时:

Get-Content : 无法检索 cmdlet 的动态参数。指定的通配符模式无效: [.srt
所在位置 行:6 字符: 5
+     type $srt|%{
+     ~~~~~~~~~
    + CategoryInfo          : InvalidArgument: ( [Get-Content],ParameterBindingException
    + FullyQualifiedErrorId : GetDynamicParametersException,Microsoft.PowerShell.Commands.GetContentCommand

Set-Content : 无法检索 cmdlet 的动态参数。指定的通配符模式无效: [.srt
所在位置 行:5 字符: 1
+ sc -enc utf8 $srt $(
+ ~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Set-Content],ParameterBindingException
    + FullyQualifiedErrorId : GetDynamicParametersException,Microsoft.PowerShell.Commands.SetContentCommand



标题中包含[时:

type : 指定路径 H:\test\完整版[ABCD].srt 处的某个对象不存在,或者已被 -Include 或 -Exclude 参数过滤掉。
所在位置 行:6 字符: 5
+     type $srt|%{
+     ~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (System.String[]:String[]) [Get-Content], Exception
    + FullyQualifiedErrorId : ItemNotFound,Microsoft.PowerShell.Commands.GetContentCommand

Set-Content : 找不到与参数名称“enc”匹配的参数。
所在位置 行:5 字符: 4
+ sc -enc utf8 $srt $(
+    ~~~~
    + CategoryInfo          : InvalidArgument: (:) [Set-Content],ParameterBindingException
    + FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Commands.SetContentCommand

而且]这个符号是可以的,很奇怪。
作者: idwma    时间: 2022-8-31 22:03

回复 12# vwfgh


    这个还真没碰到过呀
  1. #@&cls&powershell "type '%~0'|out-string|iex"&pause&exit
  2. $s=[timespan]::FromSeconds(5)
  3. dir *.srt|%{
  4. $srt=$_.fullname
  5. [io.file]::WriteAllLines($srt,$(
  6.     [io.file]::ReadAllLines($srt)|%{
  7.         if($_ -match '-->'){
  8.             $a=$_ -replace ',','.' -split '\s+-->\s+'
  9.             $f=[datetime]$a[0]
  10.             $l=[datetime]$a[1]
  11.             if($l-$f -gt $s){'{0:HH:mm:ss,fff} --> {1:HH:mm:ss,fff}' -f $f,($f+$s)}else{$_}
  12.         }else{$_}
  13.     })
  14. )
  15. }
复制代码

作者: vwfgh    时间: 2022-9-1 07:56

回复 13# idwma


完全OK了,感谢耐心解答!!!
作者: WHY    时间: 2022-9-1 14:01

Test.bat,编码为utf8 without BOM
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. chcp 65001
  4. for /f "delims=" %%i in ('dir /b *.srt') do (
  5.     (for /f "delims=" %%j in ('findstr /n .* "%%i"') do (
  6.         set "s=%%j"
  7.         if "!s: --> =!" NEQ "!s!" (
  8.             set "s=!s:*:=!"
  9.             for /f "tokens=1-8 delims=:,-> " %%A in ("!s!") do (
  10.                 set /a T1 = "((1%%A - 100) * 3600 + (1%%B - 100) * 60 + (1%%C - 100)) * 1000 + 1%%D - 1000"
  11.                 set /a T2 = "((1%%E - 100) * 3600 + (1%%F - 100) * 60 + (1%%G - 100)) * 1000 + 1%%H - 1000"
  12.                 set /a x = T2 - T1
  13.                 if !x! GTR 5000 (
  14.                     set /a T2 = T1 + 5000, ms = T2 %% 1000 + 1000, T2 /= 1000
  15.                     set /a HH = T2 /3600 + 100, mm = T2 %% 3600 / 60 + 100, ss = T2 %% 60 + 100
  16.                     set "s=%%A:%%B:%%C,%%D --> !HH:~1!:!mm:~1!:!ss:~1!,!ms:~1!"
  17.                 )
  18.             )
  19.         ) else (
  20.             set "s=!s:*:=!"
  21.         )
  22.         echo;!s!
  23.     )) > "%%i.~tmp"
  24.     move "%%i.~tmp" "%%i"
  25. )
  26. pause
复制代码

作者: WHY    时间: 2022-9-1 20:54

把 绝对路径 作为脚本参数传递给 PowerShell 脚本
get-ChildItem(dir)、get-Content(gc)、set-Content(sc) 这些 cmdlet 用参数 -LiteralPath 代替 -Path
当路径或文件名出现"["字符时可以避免报错。
  1. <# :
  2. @echo off
  3. PowerShell -c ". ([ScriptBlock]::Create((gc -Literal '%~f0') -join \"`r`n\")) '%~dp0'"
  4. pause & exit/b
  5. #>
  6. param([string]$path);
  7. $reg = '^(\d\d:\d\d:\d\d,\d\d\d)\s*-->\s*(\d\d:\d\d:\d\d,\d\d\d)$';
  8. forEach( $file In (dir -Literal $path -Filter *.srt) ){
  9.     $arr = gc -Literal $file.FullName -Enc UTF8 -ReadCount 0;
  10.     $count = $arr.Count;
  11.     for( $i = 0; $i -lt $count; $i++ ){
  12.         if( $arr[$i] -match $reg ){
  13.             $T1 = [DateTime]$matches[1].Replace(',', '.');
  14.             $T2 = [DateTime]$matches[2].Replace(',', '.');
  15.             if( ($T2 - $T1).TotalSeconds -gt 5 ){
  16.                 $arr[$i] = $matches[1] + ' --> ' + $T1.AddSeconds(5).ToString('HH:mm:ss,fff');
  17.             }
  18.         }
  19.     }
  20.     sc -Literal $file.FullName -Enc UTF8 -Value $arr;
  21. }
复制代码





欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2