forked from ableplayer/ableplayer
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathableplayer-transcript-maker.php
More file actions
executable file
·214 lines (203 loc) · 6.02 KB
/
ableplayer-transcript-maker.php
File metadata and controls
executable file
·214 lines (203 loc) · 6.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
<?php
/*
Transcript Maker (TM) for Univeral Media Player (UMP)
http://www.terrillthompson.com/ump
Author: Terrill Thompson
Version: 1.0 alpha
Last update: December 15, 2012
Produces a UMP-compatible interactive transcript from one or two WebVTT files
Output is written to the screen
Expects URLs of WebVTT files to be passed by GET
$c = URL of caption file
$d = URL of description file (optional, but highly recommended)
If anything goes wrong, writes an error code to the screen
0 = insuficcient parameters were passed by URL
1 = unable to read WebVTT file (enforced for caption file only)
2 = file is not a WebVTT file
3 = no cues were found in WebVTT file
*/
parseWebVTT($_GET['c'],$_GET['d']);
function parseWebVTT($captionUrl=NULL,$descUrl=NULL) {
if ($captionUrl) {
$captionFile = @file_get_contents($captionUrl);
if ($captionFile) {
$captionArray = toArray('captions',$captionFile);
}
else {
echo '1'; // unable to read caption file;
}
if ($descUrl) {
$descFile = @file_get_contents($descUrl);
if ($descFile) {
$descArray = toArray('desc',$descFile);
}
else {
// do nothing
// description file is not required
}
}
if (sizeof($captionArray) > 0) {
writeOutput($captionArray,$descArray);
}
else {
// do nothing
// an error has occurred (and hopefully an error code was displayed)
}
}
else {
echo '0'; // insuficcient parameters were passed by URL
}
}
function toArray($type,$content) {
//standardize on \n for eol character
$content = preg_replace("/\r\n|\r|\n/m", "\n", trim($content));
$cues = explode("\n\n",$content);
$n = 0; // counter of kept cues
if (sizeof($cues)>1) {
if (trim(strtoupper($cues[0])) == 'WEBVTT') { //spec requires WEBVTT on the first line
$i=1;
while ($i < sizeof($cues)) {
$cue = explode("\n",$cues[$i]);
if (sizeof($cue) >=2) { // this seems to be a valid cue. Keep it
$times = explode(' --> ',$cue[0]);
$c['type'][$n] = $type;
$c['start'][$n] = toSeconds(trim($times[0]));
$c['end'][$n] = toSeconds(trim($times[1]));
$cueText = $cue[1];
if(sizeof($cue) > 2) { // this is a multi-line cue
$j=2;
while ($j < sizeof($cue)) {
// ensure there's one space between cues, but not more than one
$cueText .= ' '.trim($cue[$j]);
$j++;
}
}
$c['text'][$n] = $cueText;
$n++;
}
$i++;
}
}
else {
echo '2'; // this is not a WebVTT file
}
}
else {
echo '3'; // too few cues were found
}
return $c;
}
function toSeconds($time) {
$seconds = 0;
if ($time) {
$parts = explode(':',$time);
$i=0;
while ($i < sizeof($parts)) {
$seconds = $seconds * 60 + str_replace(',','.',$parts[$i]);
$i++;
}
return $seconds;
}
}
function writeOutput($c,$d) {
// merge arrays and sort by start time
$allCues = array_merge_recursive($c,$d);
array_multisort($allCues['start'],$allCues['end'],$allCues['type'],$allCues['text']);
//echo "<pre>";
//var_dump($allCues);
//echo "</pre>";
$numCues = sizeof($allCues['start']);
if ($numCues > 0) {
echo '<div class="ump-transcript">'."\n";
$divOpen = false;
$descOpen = false;
$i=0;
while ($i < $numCues) {
$cue = trim($allCues['text'][$i]);
$cueType = $allCues['type'][$i];
// make transcript more readable by breaking divs on parenthetical or bracketed text
// brackets contain unspoken information such as sounds or speaker names
//standardize on square brackets []
// $cue = @preg_replace("(|(", "[", $cue); // this wasn't working
// $cue = @preg_replace(")|)", "]", $cue); // trying to account for various ( symbols
$cue = str_replace('(','[',$cue);
$cue = str_replace(')',']',$cue);
if ($descOpen && $cueType != 'desc') {
// close description div
echo "\n</div>\n";
$descOpen = false;
$divOpen = false;
}
// if cue contains bracketed content, or is the start of a new description
// both make good breaking points
if (substr($cue,0,1) == '[' || ($cueType =='desc' && !$descOpen)) {
if ($divOpen) {
// close the preceding div
echo "\n</div>\n\n";
if ($cueType == 'desc') {
// this is the start of a new description (following a caption)
echo '<div class="ump-desc">'."\n";
// preface description with a hidden prompt for non-visual users
echo '<span class="hidden">Description: </span>';
$descOpen = true;
}
else {
// this is the start of a new caption with bracketed content
echo "<div>\n";
}
}
else { // div is not already open
if ($cueType == 'desc') {
// this is the start of a new description
echo '<div class="ump-desc">'."\n";
// preface description with a hidden prompt for non-visual users
echo '<span class="hidden">Description: </span>';
$descOpen = true;
}
else {
// this is a new caption
echo "<div>\n";
$divOpen = true;
}
}
$bracketEndPos = strpos($cue,']');
if (substr($cue,0,1) == '[') {
echo '<span class="ump-unspoken">';
echo '['.ucfirst(trim(substr($cue,1,$bracketEndPos-1))).']';
echo "</span>\n";
if (strlen($cue) > ($bracketEndPos+1)) {
// there is additional content in this cue, not just bracketed content
$cue = substr($cue,$bracketEndPos+1);
}
else {
// nothing in this queue but bracketed text. Close the div
echo "</div>\n";
$divOpen = false;
$cue = '';
}
}
}
// now write the cue
if ($cue != '') {
if ($cueType == 'desc') {
echo $cue.' ';
}
else {
// add attributes to make this cue clickable and highlightable
// Note: tabindex="0" will be added dynamically based on user preference
echo '<span ';
echo 'data-start="'.$allCues['start'][$i].'" ';
echo 'data-end="'.$allCues['end'][$i].'">';
echo $cue.' ';
echo "</span> ";
}
}
$i++;
}
if ($divOpen) { //close it
echo "</div>\n";
}
echo "</div>\n"; //close transcript
}
}
?>