문제
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 파일을 구문 분석하고 파일의 모든 하위 저장을 변수로 인쇄해야합니다.
나는 올바른 Reg Exps를 찾을 수 없었다.이렇게 할 때 ID, 시간 및 자막 변수를 가져와야합니다.그리고 인쇄 할 때 Array () s 또는 등등이 없어야합니다.
나는 내가 인쇄해야한다는 것을 의미한다.
$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 />';
}
. 해결책
다음은 SRT 파일 행을 구문 분석하기위한 짧고 간단한 상태 시스템입니다.
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";
}
.
읽기 : 하위 립 텍스트 파일 형식
다른 팁
일치하지 않을 것입니다.
Array
([0] => '1',
[1] => '00:00:00,074 --> 00:00:02,564',
[2] => 'Previously on Breaking Bad...'.
[3] => '',
[4] => '2',
...
)
.
정규식은 해당 요소와 일치하지 않을 것입니다.
의도가 전체 파일을 하나의 긴 memory-of-a-a-a-string으로 읽는 것이면 file_get_contents를 사용하여 전체 파일 내용을 하나의 문자열로 가져옵니다.그런 다음 모든 정규식 일치를 얻으려면 preg_match_all을 사용하십시오.
그렇지 않으면 배열을 반복하려고 시도하고 다양한 정규식 패턴과 일치하여 회선이 ID인지 여부, 시간 범위 또는 텍스트를 결정하고 적절하게 수행 할 수 있습니다.분명히 귀하가 올바른 순서 (ID, 시간 범위, 텍스트)로 값을 가져 오는지 확인하려면 일부 논리가 필요할 수도 있습니다.
file()
를 사용하여 4 개의 덩어리로 4의 덩어리로 그룹을 그룹화 한 다음 마지막으로 항목을 생략 한 다음 빈 줄이므로 마지막 항목을 생략하십시오.다음과 같이 :
foreach( array_chunk( file( 'test.srt'), 4) as $entry) {
list( $number, $time, $subtitle) = $entry;
echo $number . '<br />';
echo $time . '<br />';
echo $subtitle . '<br />';
}
. .srt 파일을 배열로 변환하는 클래스를 만들었습니다. 배열의 각 항목에는 다음과 같은 속성이 있습니다.
- ID : 자막의 ID를 나타내는 숫자 (2)
- start : float, 시작 시간 (24.443)
- 끝 : 플로트, 초 단위 (27.647)
- StartString : 인간의 읽기 쉬운 형식의 시작 시간 (00 : 00 : 24.443)
- endstring : 인간의 읽을 수있는 형식의 종료 시간 (00 : 00 : 24.647)
- 지속 시간 : 자막 기간, MS (3204)
- 텍스트 : 자막의 텍스트 ( 공맨시에 통치 한 공작새가 지배 )
코드는 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
이 프로젝트를 사용할 수 있습니다 : https://github.com/captioning/captioning P>
샘플 코드 :
<?php
require_once __DIR__.'/../vendor/autoload.php';
use Captioning\Format\SubripFile;
try {
$file = new SubripFile('your_file.srt');
foreach ($file->getCues() as $line) {
echo 'start: ' . $line->getStart() . "<br />\n";
echo 'stop: ' . $line->getStop() . "<br />\n";
echo 'startMS: ' . $line->getStartMS() . "<br />\n";
echo 'stopMS: ' . $line->getStopMS() . "<br />\n";
echo 'text: ' . $line->getText() . "<br />\n";
echo "=====================<br />\n";
}
} catch(Exception $e) {
echo "Error: ".$e->getMessage()."\n";
}
.
샘플 출력 :
> php index.php
start: 00:01:48,387<br />
stop: 00:01:53,269<br />
startMS: 108387<br />
stopMS: 113269<br />
text: ┘ç┘à╪د┘ç┘┌»█î ╪▓█î╪▒┘┘ê█î╪│ ╪ذ╪د ┌ر█î┘█î╪ز ╪ذ┘┘ê╪▒█î ┘ê ┌ر╪»┌ر x265
=====================<br />
start: 00:02:09,360<br />
stop: 00:02:12,021<br />
startMS: 129360<br />
stopMS: 132021<br />
text: .┘à╪د ┘╪ذ╪د┘è╪» ╪ز┘┘ç╪د┘è┘è ╪د┘è┘╪ش╪د ╪ذ╪د╪┤┘è┘à -
┌╪▒╪د ╪ا<br />
=====================<br />
start: 00:02:12,022<br />
stop: 00:02:14,725<br />
startMS: 132022<br />
stopMS: 134725<br />
text: ..╪د┌»┘ç ┘╛╪»╪▒╪ز -
.╪د┘ê┘ ┘ç┘è┌┘ê┘é╪ز ┘à╪ز┘ê╪ش┘ç ╪▒┘╪ز┘┘à┘ê┘ ┘┘à┘è╪┤┘ç -<br />
=====================<br />
. PHP 라인 브레이크를 사용하여 수행 할 수 있습니다. 나는 그것을 성공적으로 할 수 있었다 내 코드를 보여 주겠습니다.
$srt=preg_split("/\\r\\n\\r\\n/",trim($movie->SRT));
$result[$i]['IMDBID']=$movie->IMDBID;
$result[$i]['TMDBID']=$movie->TMDBID;
.
여기 $ movie-> srt는이 질문에 게시 된 형식을 갖는 자막입니다. 우리가 보듯이, 각 공간은 두 개의 새로운 라인이며, 답변을 희망합니다.