Question

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

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

j'ai besoin d'analyser des fichiers srt avec php et d'imprimer le tout sous-marins dans le fichier avec les variables.

je n'arrivais pas à trouver le bon reg exps.lorsque vous faites cela, j'ai besoin de prendre l'id, le temps et les sous-titres des variables.et lors de l'impression de là, il ne faut pas être non array() s ou etc.doit impression tout de même que dans l'origine du fichier.

je veux dire que je doit imprimer le souhaitez;

$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...)

en passant, j'ai ce code.mais il ne voit pas les lignes.il doit être édité, mais comment?

$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 />';

}
Était-ce utile?

La solution

Voici une machine à états courte et simple pour analyser la ligne de fichier SRT par ligne:

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);

résultat:

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.
        )

)

Vous pouvez ensuite boucler sur la matrice de sous-marine ou les accéder par une matrice offset:

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

Pour afficher tous les sous-marins en boucle sur chacun et l'affichage:

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";
}

Lecture ultérieure: Format de fichier de texte de la sous-curseur

Autres conseils

Cela ne va pas correspondre car votre tableau $ SRT_FILE pourrait ressembler à ceci:

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

Votre regex ne correspond pas à aucun de ces éléments.

Si votre intention est de lire l'intégralité du fichier en une seule mémoire-hog-de-a-String, utilisez File_Get_Contents pour obtenir le contenu complet du fichier dans une chaîne.Ensuite, utilisez un Preg_Match_All pour obtenir toutes les correspondances de regex.

Sinon, vous pourriez essayer de boucler dans le tableau et essayez de faire correspondre divers modèles de regex pour déterminer si la ligne est une pièce d'identité, une plage de temps ou un texte et faites de manière appropriée.Évidemment, vous voudrez peut-être également que certaines logiques s'assurent que vous obtenez des valeurs dans le bon ordre (ID, puis la plage horaire, puis le texte).

Le groupe file() tableau en morceaux de 4 à l'aide de array_chunk(), puis omettre la dernière entrée, puisque c'est une ligne vide comme ceci:

foreach( array_chunk( file( 'test.srt'), 4) as $entry) {
    list( $number, $time, $subtitle) = $entry;
    echo $number . '<br />';
    echo $time . '<br />';
    echo $subtitle . '<br />';
}

J'ai fait une classe pour convertir un fichier .srt en tableau. Chaque entrée de la matrice présente les propriétés suivantes:

  • ID: un numéro représentant l'ID du sous-titre (2)
  • Démarrer: flotteur, l'heure de début en secondes (24.443)
  • fin: flotteur, l'heure de fin en secondes (27.647)
  • DevingString: l'heure de début du format lisible humain (00: 00: 24.443)
  • EndString: l'heure de fin du format lisible humain (00: 00: 24.647)
  • Durée: la durée du sous-titre, en MS (3204)
  • Texte: Le texte du sous-titre ( Les paons ont gouverné sur la ville de Gongmen. )

    Le code est 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];
        }
    
    
    }
    

    ou vérifier ici: https://github.com/lingtalfi/videosubtitles

Vous pouvez utiliser ce projet: https://github.com/captioning/captioning

échantillon code:

<?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";
}

Sortie d'échantillon:

> 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 />

Cela peut être fait en utilisant PHP Line-Break. Je pourrais le faire avec succès Laissez-moi montrer mon code

$srt=preg_split("/\\r\\n\\r\\n/",trim($movie->SRT));
            $result[$i]['IMDBID']=$movie->IMDBID;
            $result[$i]['TMDBID']=$movie->TMDBID;

ici $ Movie-> SRT est le sous-titre d'avoir format u posté dans cette question. Comme on le voit, chaque espace est deux nouvelles lignes, J'espère avoir une réponse.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top