Дмитрий Сергеевич (axshavan) wrote,
Дмитрий Сергеевич
axshavan

PHP .srt shifter

Вдруг приспичило мне посмотреть фильм с субтитрами. Ну, допустим, анимешный мультик без русской аудиодорожки. Но оказалось, что огромное расхождение во времени между репликами персонажей в мултике и в субтитрах. Я не долго горевал, а набросал на PHP скриптик для сдвига субтитров формата .SRT на указанную величину.

$ php srt_shifter.php subtitles.srt '-31.5'
Сдвинет временные метки всех субтитров в файле subtitles.srt на 31.5 секунду раньше.

/**
 * Сдвиг времени.
 * @param  array $time  = array('h' => часы, 'm' => минуты, 's' => секунды) что сдвигать
 * @param  array $shift = array('h' => часы, 'm' => минуты, 's' => секунды) на сколько сдвигать
 * @return array('h' => часы, 'm' => минуты, 's' => секунды)
 */
function shifttime($time, $shift)
{
 $result      = array();
 
 // секунды
 $result['s'] = $time['s'] + $shift['s'];
 if($result['s'] >= 60)
 {
  $result['s'] -= 60;
  $shift['m']++;
 }
 if($result['s'] < 0)
 {
  $result['s'] -= 60;
  $shift['m']--;
 }
 $result['s'] = sprintf('%.3f', $result['s']);
 if($result['s'] < 10)
 {
  $result['s'] = '0'.$result['s'];
 }
 
 // минуты
 $result['m'] = $time['m'] + $shift['m'];
 if($result['m'] >= 60)
 {
  $result['m'] -= 60;
  $shift['h']++;
 }
 if($result['m'] < 0)
 {
  $result['m'] -= 60;
  $shift['h']--;
 }
 if($result['m'] < 10)
 {
  $result['m'] = '0'.$result['m'];
 }
 
 // часы
 $result['h'] = $time['h'] + $shift['h'];
 if($result['h'] < 0)
 {
  // отрицательное время
  return array('s' => '00,000', 'm' => '00', 'h' => '00');
 }
 if($result['h'] < 10)
 {
  $result['h'] = '0'.$result['h'];
 }
 
 return $result;
}

// проверка вводимых параметров
if(!$argv[1])
{
 echo "No file specified\n";
 die();
}
if(!$argv[2])
{
 echo "No shift specified\n";
 die();
}
$shift = (float)$argv[2];
if(!$shift)
{
 echo "Shift must be floationg number of seconds\n";
 die();
}

// открытие файлов
$fi = fopen($argv[1], "r");
if(!$fi)
{
 echo "Cannot open input file for reading\n";
 die();
}
$fo = fopen("out.srt", "w");
if(!$fo)
{
 echo "Cannot open output file for writing\n";
 die();
}

// небольшая подготовка
$shift_h = floor($shift / 3600); // сдвиг в часах, вряд ли пригодится, но учесть надо
$shift_m = floor(($shift - $shift_h * 3600) / 60); // сдвиг в минутах
$shift   = $shift - $shift_h * 3600 - $shift_m * 60; // оставшийся сдвиг в секундах

// собственно процесс сдвига
while($s = fgets($fi))
{
 // hh:mm:ss,sss --> hh:mm:ss,sss
 if(preg_match('/([\d]{2,})\:([\d]{2})\:([\d]{2},[\d]{3}) --> ([\d]{2,})\:([\d]{2})\:([\d]{2},[\d]{3})/', $s, $_ar))
 {
  $t1 = shifttime
  (
   array
   (
    'h' => $_ar[1],
    'm' => $_ar[2],
    's' => str_replace(',', '.', $_ar[3])
   ),
   array
   (
    'h' => $shift_h,
    'm' => $shift_m,
    's' => $shift
   )
  );
  $t2 = shifttime
  (
   array
   (
    'h' => $_ar[4],
    'm' => $_ar[5],
    's' => str_replace(',', '.', $_ar[6])
   ),
   array
   (
    'h' => $shift_h,
    'm' => $shift_m,
    's' => $shift
   )
  );
  $s = $t1['h'].':'.$t1['m'].':'.str_replace('.', ',', $t1['s']).' --> '.$t2['h'].':'.$t2['m'].':'.str_replace('.', ',', $t2['s'])."\n";
 }
 fputs($fo, $s);
}

// закрытие файлов
fclose($fi);
fclose($fo);


Смысла подписывать что-нибудь типа "published under GNU GPL license" нет, такое любой школьник накатает с полтычка.

Оришинал записи http://axshavan.blogspot.com/2011/04/php-srt-shifter.html
Tags: web, кино
Subscribe

  • Post a new comment

    Error

    Comments allowed for friends only

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 4 comments