4

I've searched and found nothing similar.
What I'm trying to achieve is creating a simple PHP/js/jq script that can add or subtract seconds from a .srt file. I'm not sure if regex is something I should go with to achieve it or something else.
The user will upload/copy the text of the srt file and then add the number of seconds to an input box that they want to add or subtract seconds from SRT.

For example if user adds +4 seconds to the following srt file:

0
00:00:04,594 --> 00:00:10,594
this is a subtitle

1
00:00:40,640 --> 00:00:46,942
this is another subtitle

2
00:02:05,592 --> 00:02:08,694
this is one more subtitle

It should look like this:

0
00:00:08,594 --> 00:00:14,594
this is a subtitle

1
00:00:44,640 --> 00:00:50,942
this is another subtitle

2
00:02:09,592 --> 00:02:12,694
this is one more subtitle
Casimir et Hippolyte
  • 88,009
  • 5
  • 94
  • 125
Amit
  • 187
  • 2
  • 15
  • The way you put it the question sounds too broad. Please narrow the task down, and share what you have tried so far. – Wiktor Stribiżew Sep 07 '15 at 21:48
  • 1
    read in to array, loop line by line extract time, add seconds write new file - at least make a start –  Sep 07 '15 at 21:56
  • [Wikipedia's entry on .srt files](https://en.wikipedia.org/wiki/SubRip#SubRip_.28.srt.29_structure_examples) seems to suggest that the caption number appears on the line before the time/subtitle. Just wondering if this is a hard requirement as it might impact an answer. – Darragh Enright Sep 07 '15 at 21:59
  • I agree... i would not regex this. There is a well defined simple format... write a parser that parses lines. – prodigitalson Sep 07 '15 at 22:16

2 Answers2

2

Here's a solution in PHP, which is one of your specified languages.

If you can represent the time offset that you want to apply as a string the you can use DateTime methods DateTime::modify(), DateTime::createFromFormat() and preg_replace_callback() to achieve what you want to do.

The SubRip Wikipedia entry specifies the timecode format as:

hours:minutes:seconds,milliseconds

So we can write a regex to capture this; e.g: /(\d+:\d+:\d+,\d+)/ - although you might wish to refine this.

Given a scenario where your .srt file is read into a string $srt, and you want to increase the times by 5 seconds:

<?php

$srt = <<<EOL

0
00:00:04,594 --> 00:00:10,594 this is a subtitle

1
00:00:40,640 --> 00:00:46,942 this is a subtitle

2
00:02:05,592 --> 00:02:08,694 this is a subtitle
EOL;

$regex  = '/(\d+:\d+:\d+,\d+)/';
$offset = '+5 seconds';

$result = preg_replace_callback($regex, function($match) use ($offset) {
    $dt = DateTime::createFromFormat('H:i:s,u', $match[0]);
    $dt->modify($offset);
    return $dt->format('H:i:s,u');
}, $srt);

echo $result;

On each $match, use DateTime::createFromFormat() to convert the matching timecode into a DateTime object, which you can then modify and reformat as a string representing the offset time.

You can use a variety of offset values with DateTime::modify() including, but not limited to: +1 minute, -30 seconds, 1 hour 2 minutes and so on. Read the linked documentation for more details.

This yields:

0
00:00:09,594000 --> 00:00:15,594000 this is a subtitle

1
00:00:45,640000 --> 00:00:51,942000 this is a subtitle

2
00:02:10,592000 --> 00:02:13,694000 this is a subtitle

Hope this helps :)

Darragh Enright
  • 13,676
  • 7
  • 41
  • 48
0

If you would like to support more formats on your website, you can use library:

$user_subtitles = $_POST['user_subtitles'];

$subtitles = Subtitles::loadFromString($user_subtitles, 'srt'); // you can load different formats of subtitles
$subtitles->time(4); // +4 seconds

echo $subtitles->content();

https://github.com/mantas-done/subtitles

Mantas D
  • 3,993
  • 3
  • 26
  • 26
  • I tried to get your promising library working, however, did not work out. I tried `require_once("Subtitles.php")`, then `use \Done\Subtitles\Subtitles;` and run. Result: `Fatal error: Uncaught Error: Class 'Done\Subtitles\Helpers' not found`. Then included the Helpers.php and the php files in the Converter folder, next error: `Interface 'Done\Subtitles\ConverterContract' not found` - Could you complete your script above? – Avatar Nov 18 '17 at 21:53
  • Hi, you need to load it using "composer". Or just load all the files like you did with required_once. There aren't a lot of them. – Mantas D Nov 21 '17 at 19:38