Index: trunk/extensions/OggHandler/README |
— | — | @@ -6,16 +6,25 @@ |
7 | 7 | |
8 | 8 | require( "$IP/extensions/OggHandler/OggHandler.php" ); |
9 | 9 | |
10 | | -You will also need a copy of ffmpeg on the server. You can get it from: |
| 10 | +FFmpeg |
| 11 | +------ |
11 | 12 | |
12 | | - http://ffmpeg.mplayerhq.hu/ |
| 13 | +We use FFmpeg for creating still images of videos, you will need a copy on your |
| 14 | +server. Unfortunately the current version of FFmpeg has a bug which makes it |
| 15 | +extremely slow when used in this way. Our ffmpeg-bugfix.diff will fix this. |
13 | 16 | |
14 | | -Set the binary location with: |
| 17 | +Download source: http://ffmpeg.mplayerhq.hu/download.html |
| 18 | +About the bug: http://bugzilla.mplayerhq.hu/show_bug.cgi?id=892 |
15 | 19 | |
| 20 | +Set the FFmpeg binary location with: |
| 21 | + |
16 | 22 | $wgFFmpegLocation = '/path/to/ffmpeg'; |
17 | 23 | |
18 | 24 | after the require line above. |
19 | 25 | |
| 26 | +Cortado |
| 27 | +------- |
| 28 | + |
20 | 29 | The bundled Cortado player is licensed under the GPL, the source is available from: |
21 | 30 | |
22 | 31 | http://www.flumotion.net/cortado/ |
— | — | @@ -24,11 +33,17 @@ |
25 | 34 | the patch is in cortado-tweak.diff. The recompiled binary is at |
26 | 35 | cortado-ovt-stripped-0.2.2.1-patched.jar . |
27 | 36 | |
| 37 | +PEAR File_Ogg |
| 38 | +------------- |
| 39 | + |
28 | 40 | The PEAR directory contains a fork of the File_Ogg package, licensed under the |
29 | 41 | LGPL. The stock File_Ogg will not work -- I have made many aggressive changes |
30 | 42 | including support for stream formats other than Vorbis. I'll try to get my |
31 | 43 | changes committed to the official PEAR tree at some point in the future. |
32 | 44 | |
| 45 | +Graphics |
| 46 | +-------- |
| 47 | + |
33 | 48 | The icons play.png, pause.png, stop.png and info.png are from the Crystal Project: |
34 | 49 | |
35 | 50 | http://www.everaldo.com/crystal/ |
Index: trunk/extensions/OggHandler/ffmpeg-bugfix.diff |
— | — | @@ -0,0 +1,86 @@ |
| 2 | +Index: libavformat/ogg2.c |
| 3 | +=================================================================== |
| 4 | +--- libavformat/ogg2.c (revision 10293) |
| 5 | +@@ -466,8 +466,9 @@ |
| 6 | + ogg_get_length (AVFormatContext * s) |
| 7 | + { |
| 8 | + ogg_t *ogg = s->priv_data; |
| 9 | +- int idx = -1, i; |
| 10 | +- offset_t size, end; |
| 11 | ++ int i, streams_found; |
| 12 | ++ offset_t size, search_start, search_end; |
| 13 | ++ int64_t duration; |
| 14 | + |
| 15 | + if(s->pb.is_streamed) |
| 16 | + return 0; |
| 17 | +@@ -479,33 +480,49 @@ |
| 18 | + size = url_fsize(&s->pb); |
| 19 | + if(size < 0) |
| 20 | + return 0; |
| 21 | +- end = size > MAX_PAGE_SIZE? size - MAX_PAGE_SIZE: size; |
| 22 | ++ search_start = size > MAX_PAGE_SIZE? size - MAX_PAGE_SIZE: size; |
| 23 | ++ search_end = size; |
| 24 | + |
| 25 | + ogg_save (s); |
| 26 | +- url_fseek (&s->pb, end, SEEK_SET); |
| 27 | + |
| 28 | +- while (!ogg_read_page (s, &i)){ |
| 29 | +- if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 && |
| 30 | +- ogg->streams[i].codec) |
| 31 | +- idx = i; |
| 32 | +- } |
| 33 | ++ /* Seek back from the end of the file until we find the duration of all of the streams */ |
| 34 | ++ streams_found = 0; |
| 35 | ++ while (streams_found < ogg->nstreams && search_start > 0) { |
| 36 | ++ url_fseek (&s->pb, search_start, SEEK_SET); |
| 37 | ++ while (!ogg_read_page (s, &i) && url_ftell (&s->pb) < search_end) { |
| 38 | ++ if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 && |
| 39 | ++ ogg->streams[i].codec) |
| 40 | ++ { |
| 41 | ++ duration = ogg_gptopts (s, i, ogg->streams[i].granule); |
| 42 | ++ if (s->streams[i]->duration == AV_NOPTS_VALUE) { |
| 43 | ++ s->streams[i]->duration = duration; |
| 44 | ++ streams_found++; |
| 45 | ++ } else if (duration > s->streams[i]->duration) { |
| 46 | ++ s->streams[i]->duration = duration; |
| 47 | ++ } |
| 48 | ++ } |
| 49 | ++ } |
| 50 | ++ search_start -= MAX_PAGE_SIZE; |
| 51 | ++ search_end -= MAX_PAGE_SIZE; |
| 52 | ++ } |
| 53 | + |
| 54 | +- if (idx != -1){ |
| 55 | +- s->streams[idx]->duration = |
| 56 | +- ogg_gptopts (s, idx, ogg->streams[idx].granule); |
| 57 | +- } |
| 58 | ++ ogg->size = size; |
| 59 | + |
| 60 | +- ogg->size = size; |
| 61 | ++ /* Go back to the start and find the start time for each stream */ |
| 62 | + ogg_restore (s, 0); |
| 63 | + ogg_save (s); |
| 64 | +- while (!ogg_read_page (s, &i)) { |
| 65 | +- if (i == idx && ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0) |
| 66 | +- break; |
| 67 | +- } |
| 68 | +- if (i == idx) { |
| 69 | +- s->streams[idx]->start_time = ogg_gptopts (s, idx, ogg->streams[idx].granule); |
| 70 | +- s->streams[idx]->duration -= s->streams[idx]->start_time; |
| 71 | +- } |
| 72 | ++ streams_found = 0; |
| 73 | ++ /* Reset the start time to AV_NOPTS_VALUE, just in case it isn't already */ |
| 74 | ++ for (i = 0; i < ogg->nstreams; i++) { |
| 75 | ++ s->streams[i]->start_time = AV_NOPTS_VALUE; |
| 76 | ++ } |
| 77 | ++ while (!ogg_read_page (s, &i) && streams_found < ogg->nstreams) { |
| 78 | ++ if (s->streams[i]->start_time == AV_NOPTS_VALUE && ogg->streams[i].granule != -1) { |
| 79 | ++ streams_found++; |
| 80 | ++ s->streams[i]->start_time = ogg_gptopts (s, i, ogg->streams[i].granule); |
| 81 | ++ s->streams[i]->duration -= s->streams[i]->start_time; |
| 82 | ++ } |
| 83 | ++ } |
| 84 | + ogg_restore (s, 0); |
| 85 | + |
| 86 | + return 0; |