web-dev-qa-db-ja.com

字幕の重複:字幕の2つのタイムライン(例:00:18:06と00:16:01)を比較して、重複している場合はそのうちの1つを上書きする方法は?

一連のsrtファイル(映画の字幕)があり、タイムラインの一部がビデオ上で互いに重なっています!これは、一部のタイムラインが映画よりも1〜2秒長く表示され、次のタイムラインと競合することを意味します。

例えば:

1
00:00:01.000 --> 00:00:07.000
The following content is provided

2
00:00:04.000 --> 00:00:10.000
under a Creative Commons license.

'07'は '04'と重なります!

タイムラインの最初の部分を前の行の2番目の部分に上書きしたい。すべてのタイムラインが互いに干渉しないように注意してください。それらのいくつかは正しく、次のタイムラインよりも短いです!干渉はそれらの一部にのみあります。

2
mini

私は #awk IRC でこの質問をしました @ geirha は以下の素晴らしいスクリプトを書きました。スクリプトは他の人にも使えるかもしれません。映画の字幕作成中に人為的エラーが発生するため、字幕の重複問題がよく発生します。

タイムラインが以下の形式であるとします。
A --> B
C --> D

BをCで置き換える:

gawk '
  BEGIN {
    RS = "";
    OFS = FS = "\n";
    getline;
    n = split($0, prev_rec);
    split($2, prev_time, / --> /);
  }
  {
    split($2, a, / --> /);
    if (a[1] < prev_time[2])
      prev_rec[2] = prev_time[1]" --> "a[1];
    for (i=1;i<=n;i++)
      print prev_rec[i];
    printf("\n");
    n = split($0, prev_rec);
    split($2, prev_time, / --> /)
  }
  END {
    print
  }' SUBTITLE.srt > RESULT.srt

上記のコードは[〜#〜] b [〜#〜][〜#〜] c [を比較します〜#〜]このように:

B> C =>の場合、その魅力的なコマンドを実行してBを置き換えます。
B <C =>の場合、何もしないでください!


CをBで置き換える:

gawk '
  BEGIN {
    RS="";
    OFS=FS="\n";
    prev="00:00:00"
  }
  {
    split($2,a,/ --> /);
    if
      (a[1] < prev) $2=prev" --> "a[2];
      print $0"\n"; prev=a[2]
  }' SUBTITLE.srt > RESULT.srt

フォルダ内の一定量のsrtファイルでスクリプトを使用するには:

for file in *.srt
  do xxx "$file" > "$file.tmp" && mv "$file.tmp" "$file";
done

xxxを適切なスクリプトコードに置き換えます!

2
mini