summaryrefslogtreecommitdiff
path: root/videodata.php
diff options
context:
space:
mode:
authorccd0 <admin@containerchan.org>2013-11-30 02:07:05 -0800
committerccd0 <admin@containerchan.org>2013-11-30 02:07:05 -0800
commit14ac1b562db32b68d684fefdec7d3e17b83ed745 (patch)
tree1ff1d92abe0edaf117fa52e34b4f7a27f270ab4c /videodata.php
parent2175e848343084f985e2eaaea056b6be6244cb63 (diff)
clean up frame extraction code
Diffstat (limited to 'videodata.php')
-rw-r--r--videodata.php89
1 files changed, 72 insertions, 17 deletions
diff --git a/videodata.php b/videodata.php
index 3fe9eeee..ec302fdc 100644
--- a/videodata.php
+++ b/videodata.php
@@ -1,22 +1,77 @@
<?php
require dirname(__FILE__) . '/matroska.php';
-// Header for single VPx keyframe
-function vpxFrameHeader($size, $width, $height, $codecID) {
- return "\x1A\x45\xDF\xA3\x9F\x42\x86\x81\x01\x42\xF7\x81\x01\x42\xF2\x81"
- . "\x04\x42\xF3\x81\x08\x42\x82\x84\x77\x65\x62\x6D\x42\x87\x81\x02"
- . "\x42\x85\x81\x02\x18\x53\x80\x67\x08" . pack('N', $size + 173) . "\x11\x4D\x9B"
- . "\x74\xB8\x4D\xBB\x8B\x53\xAB\x84\x15\x49\xA9\x66\x53\xAC\x81\x3D"
- . "\x4D\xBB\x8B\x53\xAB\x84\x16\x54\xAE\x6B\x53\xAC\x81\x58\x4D\xBB"
- . "\x8B\x53\xAB\x84\x1C\x53\xBB\x6B\x53\xAC\x81\x85\x4D\xBB\x8B\x53"
- . "\xAB\x84\x1F\x43\xB6\x75\x53\xAC\x81\x97\x15\x49\xA9\x66\x96\x2A"
- . "\xD7\xB1\x83\x0F\x42\x40\x44\x89\x84\x41\x20\x00\x00\x4D\x80\x81"
- . "\x66\x57\x41\x81\x66\x16\x54\xAE\x6B\xA8\xAE\xA6\xD7\x81\x01\x73"
- . "\xC5\x81\x01\x83\x81\x01\x23\xE3\x83\x83\x98\x96\x80\x86\x85" . $codecID
- . "\xE0\x8C\xB0\x84" . pack('N', $width) . "\xBA\x84" . pack('N', $height)
- . "\x1C\x53\xBB\x6B\x8D\xBB\x8B\xB3\x81\x00\xB7\x86\xF7\x81"
- . "\x01\xF1\x81\x97\x1F\x43\xB6\x75\x08" . pack('N', $size + 13) . "\xE7\x81\x00"
- . "\xA3\x08" . pack('N', $size + 4) . "\x81\x00\x00\x80";
+// Make video from single VPx keyframe
+function muxVPxFrame($width, $height, $codecID, $data) {
+ $size = strlen($data);
+ $lenSeekHead = 61;
+ $lenCues = 18;
+ $ebml = encodeElement('EBML',
+ encodeElement('EBMLVersion', "\x01")
+ . encodeElement('EBMLReadVersion', "\x01")
+ . encodeElement('EBMLMaxIDLength', "\x04")
+ . encodeElement('EBMLMaxSizeLength', "\x08")
+ . encodeElement('DocType', "webm")
+ . encodeElement('DocTypeVersion', "\x02")
+ . encodeElement('DocTypeReadVersion', "\x02")
+ );
+ $info = encodeElement('Info',
+ encodeElement('TimecodeScale', "\x0F\x42\x40")
+ . encodeElement('Duration', "\x41\x20\x00\x00")
+ . encodeElement('MuxingApp', 'f')
+ . encodeElement('WritingApp', 'f')
+ );
+ $tracks = encodeElement('Tracks',
+ encodeElement('TrackEntry',
+ encodeElement('TrackNumber', "\x01")
+ . encodeElement('TrackUID', "\x01")
+ . encodeElement('TrackType', "\x01")
+ . encodeElement('DefaultDuration', "\x98\x96\x80")
+ . encodeElement('CodecID', $codecID)
+ . encodeElement('Video',
+ encodeElement('PixelWidth', pack('N', $width))
+ . encodeElement('PixelHeight', pack('N', $height))
+ )
+ )
+ );
+ $cues = encodeElement('Cues',
+ encodeElement('CuePoint',
+ encodeElement('CueTime', "\x00")
+ . encodeElement('CueTrackPositions',
+ encodeElement('CueTrack', "\x01")
+ . encodeElement('CueClusterPosition', chr($lenSeekHead + strlen($info) + strlen($tracks) + $lenCues))
+ )
+ )
+ );
+ $seekHead = encodeElement('SeekHead',
+ encodeElement('Seek',
+ encodeElement('SeekID', encodeElementName('Info'))
+ . encodeElement('SeekPosition', chr($lenSeekHead))
+ )
+ . encodeElement('Seek',
+ encodeElement('SeekID', encodeElementName('Tracks'))
+ . encodeElement('SeekPosition', chr($lenSeekHead + strlen($info)))
+ )
+ . encodeElement('Seek',
+ encodeElement('SeekID', encodeElementName('Cues'))
+ . encodeElement('SeekPosition', chr($lenSeekHead + strlen($info) + strlen($tracks)))
+ )
+ . encodeElement('Seek',
+ encodeElement('SeekID', encodeElementName('Cluster'))
+ . encodeElement('SeekPosition', chr($lenSeekHead + strlen($info) + strlen($tracks) + $lenCues))
+ )
+ );
+ $cluster = "\x1F\x43\xB6\x75\x08" . pack('N', $size + 13) . (
+ //. encodeElement('Cluster',
+ encodeElement('Timecode', "\x00")
+ . "\xA3\x08" . pack('N', $size + 4) . ("\x81\x00\x00\x80" . $data)
+ //. encodeElement('SimpleBlock', "\x81\x00\x00\x80" . $data)
+ );
+ $segment = "\x18\x53\x80\x67\x08" . pack('N', $size + 173) . (
+ // . encodeElement('Segment',
+ $seekHead . $info . $tracks . $cues . $cluster
+ );
+ return $ebml . $segment;
}
// Locate first VPx keyframe of track $trackNumber after timecode $skip
@@ -120,7 +175,7 @@ function videoData($filename) {
}
$frame = firstVPxFrame($segment, $trackNumber, $skip);
if (!isset($frame)) throw new Exception('no keyframes');
- $data['frame'] = vpxFrameHeader($frame->size(), $pixelWidth, $pixelHeight, $codecID) . $frame->readAll();
+ $data['frame'] = muxVPxFrame($pixelWidth, $pixelHeight, $codecID, $frame->readAll());
} catch (Exception $e) {
error_log($e->getMessage());