4
1
00:00:00,074 --> 00:00:02,564
Previously on Breaking Bad...

2
00:00:02,663 --> 00:00:04,393
Words...

phpでsrtファイルを解析し、変数を使用してファイル内のすべてのサブファイルを出力する必要があります。

適切なregexpsが見つかりませんでした。これを行うとき、私はid、time、およびsubtitle変数を取得する必要があります。また、印刷する場合、array()などは元のファイルとまったく同じように印刷する必要があります。

つまり、私は次のように印刷する必要があります。

$number <br> (e.g. 1)
$time <br> (e.g. 00:00:00,074 --> 00:00:02,564)
$subtitle <br> (e.g. Previously on Breaking Bad...)

ちなみに私はこのコードを持っています。しかし、それは線を見ていません。編集する必要がありますが、どのように?

$srt_file = file('test.srt',FILE_IGNORE_NEW_LINES);
$regex = "/^(\d)+ ([\d]+:[\d]+:[\d]+,[\d]+) --> ([\d]+:[\d]+:[\d]+,[\d]+) (\w.+)/";

foreach($srt_file as $srt){

    preg_match($regex,$srt,$srt_lines);

    print_r($srt_lines);
    echo '<br />';

}
4

7 に答える 7

12

以下は、SRT ファイルを 1 行ずつ解析するための簡潔で単純なステート マシンです。

define('SRT_STATE_SUBNUMBER', 0);
define('SRT_STATE_TIME',      1);
define('SRT_STATE_TEXT',      2);
define('SRT_STATE_BLANK',     3);

$lines   = file('test.srt');

$subs    = array();
$state   = SRT_STATE_SUBNUMBER;
$subNum  = 0;
$subText = '';
$subTime = '';

foreach($lines as $line) {
    switch($state) {
        case SRT_STATE_SUBNUMBER:
            $subNum = trim($line);
            $state  = SRT_STATE_TIME;
            break;

        case SRT_STATE_TIME:
            $subTime = trim($line);
            $state   = SRT_STATE_TEXT;
            break;

        case SRT_STATE_TEXT:
            if (trim($line) == '') {
                $sub = new stdClass;
                $sub->number = $subNum;
                list($sub->startTime, $sub->stopTime) = explode(' --> ', $subTime);
                $sub->text   = $subText;
                $subText     = '';
                $state       = SRT_STATE_SUBNUMBER;

                $subs[]      = $sub;
            } else {
                $subText .= $line;
            }
            break;
    }
}

if ($state == SRT_STATE_TEXT) {
    // if file was missing the trailing newlines, we'll be in this
    // state here.  Append the last read text and add the last sub.
    $sub->text = $subText;
    $subs[] = $sub;
}

print_r($subs);

結果:

Array
(
    [0] => stdClass Object
        (
            [number] => 1
            [stopTime] => 00:00:24,400
            [startTime] => 00:00:20,000
            [text] => Altocumulus clouds occur between six thousand
        )

    [1] => stdClass Object
        (
            [number] => 2
            [stopTime] => 00:00:27,800
            [startTime] => 00:00:24,600
            [text] => and twenty thousand feet above ground level.
        )

)

次に、サブルーチンの配列をループするか、配列オフセットでアクセスできます。

echo $subs[0]->number . ' says ' . $subs[0]->text . "\n";

それぞれをループして表示することにより、すべてのサブを表示するには:

foreach($subs as $sub) {
    echo $sub->number . ' begins at ' . $sub->startTime .
         ' and ends at ' . $sub->stopTime . '.  The text is: <br /><pre>' .
         $sub->text . "</pre><br />\n";
}

さらに読む: SubRip テキスト ファイル形式

于 2012-07-25T22:01:42.137 に答える
1

$srt_file 配列は次のようになるため、これは一致しません。

Array
([0] => '1',
[1] => '00:00:00,074 --> 00:00:02,564',
[2] => 'Previously on Breaking Bad...'.
[3] => '',
[4] => '2',
...
)

あなたの正規表現は、これらの要素のいずれとも一致しません。

ファイル全体を 1 つの長いメモリを占有する文字列に読み込むことが目的の場合は、file_get_contents を使用して、ファイルの内容全体を 1 つの文字列に取得します。次に、preg_match_all を使用してすべての正規表現の一致を取得します。

それ以外の場合は、配列をループして、さまざまな正規表現パターンを照合して、行が ID、時間範囲、またはテキストであるかどうかを判断し、適切に処理しようとする可能性があります。明らかに、正しい順序 (ID、時間範囲、テキスト) で値を取得していることを確認するためのロジックも必要になる場合があります。

于 2012-07-25T21:55:04.780 に答える
1

file()を使用して配列を 4 つのチャンクにグループ化しarray_chunk()、次のような空白行であるため、最後のエントリを省略します。

foreach( array_chunk( file( 'test.srt'), 4) as $entry) {
    list( $number, $time, $subtitle) = $entry;
    echo $number . '<br />';
    echo $time . '<br />';
    echo $subtitle . '<br />';
}
于 2012-07-25T22:01:13.183 に答える
0

.srt ファイルを配列に変換するクラスを作成しました。配列の各エントリには、次のプロパティがあります。

  • id: 字幕の ID を表す数値 (2)
  • start: float、秒単位の開始時間 (24.443)
  • end: float、秒単位の終了時間 (27.647)
  • startString: 人間が読める形式の開始時間 (00:00:24.443)
  • endString: 人間が読める形式の終了時間 (00:00:24.647)
  • duration: 字幕の長さ (ms (3204))
  • text: サブタイトルのテキスト (孔雀が公門市を支配した。 )

コードはphp7です:

<?php

namespace VideoSubtitles\Srt;


class SrtToArrayTool
{


    public static function getArrayByFile(string $file): array
    {

        $ret = [];

        $gen = function ($filename) {
            $file = fopen($filename, 'r');
            while (($line = fgets($file)) !== false) {
                yield rtrim($line);
            }
            fclose($file);
        };

        $c = 0;
        $item = [];
        $text = '';
        $n = 0;
        foreach ($gen($file) as $line) {

            if ('' !== $line) {
                if (0 === $n) {
                    $item['id'] = $line;
                    $n++;
                }
                elseif (1 === $n) {
                    $p = explode('-->', $line);
                    $start = str_replace(',', '.', trim($p[0]));
                    $end = str_replace(',', '.', trim($p[1]));
                    $startTime = self::toMilliSeconds(str_replace('.', ':', $start));
                    $endTime = self::toMilliSeconds(str_replace('.', ':', $end));
                    $item['start'] = $startTime / 1000;
                    $item['end'] = $endTime / 1000;
                    $item['startString'] = $start;
                    $item['endString'] = $end;
                    $item['duration'] = $endTime - $startTime;
                    $n++;
                }
                else {
                    if ($n >= 2) {
                        if ('' !== $text) {
                            $text .= PHP_EOL;
                        }
                        $text .= $line;
                    }
                }
            }
            else {
                if (0 !== $n) {
                    $item['text'] = $text;
                    $ret[] = $item;
                    $text = '';
                    $n = 0;
                }
            }
            $c++;
        }
        return $ret;
    }


    private static function toMilliSeconds(string $duration): int
    {
        $p = explode(':', $duration);
        return (int)$p[0] * 3600000 + (int)$p[1] * 60000 + (int)$p[2] * 1000 + (int)$p[3];
    }


}

または、こちらで確認してください: https://github.com/lingtalfi/VideoSubtitles

于 2016-03-14T21:36:10.007 に答える