Added AVI x-msvideo parsing

This commit is contained in:
2024-09-24 21:55:40 +10:00
parent 06b8542de6
commit d912d35b87
15 changed files with 681 additions and 27 deletions

View File

@@ -0,0 +1,50 @@
<?php
namespace App\Media\MSVideo\Containers\rlist;
use Illuminate\Support\Arr;
use App\Media\MSVideo\Container;
class avih extends Container
{
protected const unpack = [
'tbframe'=>['V',4],
'mdr'=>['V',4],
'PG'=>['V',4],
'flags'=>['V',4],
'frames'=>['V',4],
'init_frames'=>['V',4],
'streams'=>['V',4],
'buffer_size'=>['V',4],
'width'=>['V',4],
'height'=>['V',4],
'time_scale'=>['V',4],
'data_rate'=>['V',4],
'start_time'=>['V',4],
'data_length'=>['V',4],
];
public function __construct(int $offset,int $size,string $filename,bool $be,?string $data)
{
parent::__construct($offset,$size,$filename,$be,$data);
$this->cache = $this->cache($data);
// For debugging
if (FALSE)
$this->debug = hex_dump($data ?: $this->data());
}
public function __get(string $key): mixed
{
switch ($key) {
case 'height':
case 'width':
return Arr::get($this->cache,$key);
default:
return parent::__get($key);
}
}
}

View File

@@ -0,0 +1,30 @@
<?php
namespace App\Media\MSVideo\Containers\rlist;
use App\Media\MSVideo\Container;
class isft extends Container
{
public function __construct(int $offset,int $size,string $filename,bool $be,?string $data)
{
parent::__construct($offset,$size,$filename,$be);
$this->cache = collect(['software'=>rtrim($data)]);
// For debugging
if (FALSE)
$this->debug = hex_dump($data ?: $this->data());
}
public function __get(string $key): mixed
{
switch ($key) {
case 'software':
return $this->cache->get('software');
default:
return parent::__get($key);
}
}
}

View File

@@ -0,0 +1,10 @@
<?php
namespace App\Media\MSVideo\Containers\rlist;
use App\Media\MSVideo\Containers\junk as JunkContainer;
class junk extends JunkContainer
{
}

View File

@@ -0,0 +1,59 @@
<?php
namespace App\Media\MSVideo\Containers\rlist;
use Illuminate\Support\Arr;
use App\Media\MSVideo\Container;
class movi extends Container
{
public function __construct(int $offset,int $size,string $filename,bool $be)
{
parent::__construct($offset,$size,$filename,$be);
// For debugging
if (FALSE)
$this->debug = hex_dump($data ?: $this->data());
}
public function __get(string $key): mixed
{
switch ($key) {
case 'signature':
return $this->signature();
default:
return parent::__get($key);
}
}
/**
* Calculate the signature of the data
*
* @param string $alg
* @return string
*/
private function signature(string $alg='sha1'): string
{
if (! Arr::has($this->cache,'signature')) {
if ($this->size) {
$this->fopen();
$hash = hash_init($alg);
while (!is_null($read = $this->fread(16384)))
hash_update($hash, $read);
$this->fclose();
$this->cache['signature'] = hash_final($hash);
} else {
$this->cache['signature'] = NULL;
}
}
return $this->cache['signature'];
}
}

View File

@@ -0,0 +1,10 @@
<?php
namespace App\Media\MSVideo\Containers\rlist;
use App\Media\MSVideo\Containers\rlist as ListContainer;
class rlist extends ListContainer
{
}

View File

@@ -0,0 +1,61 @@
<?php
namespace App\Media\MSVideo\Containers\rlist;
// https://cdn.hackaday.io/files/274271173436768/avi.pdf
use Illuminate\Support\Arr;
use App\Media\MSVideo\Container;
class strh extends Container
{
protected const unpack = [
'type'=>['a4',4], // FCC type
'handler'=>['a4',4], // FourCC of codec to be used
'flags'=>['a4',4],
'priority'=>['v',2],
'language'=>['v',2],
'init_frames'=>['V',4], // Number of the First block of the stream that is present in the file.
'scale'=>['V',4],
'rate'=>['V',4],
'start'=>['V',4], // Start time of stream.
'length'=>['V',4], // Size of stream in units as defined in dwRate and dwScale
'buffer_size'=>['V',4], // Size of Buffer necessary to store blocks of that stream. Can be 0 (in that case the application has to guess)
'quality'=>['V',4],
'sample_size'=>['V',4], // number of bytes of one stream atom
'frame'=>['V',4],
];
public function __construct(int $offset,int $size,string $filename,bool $be,?string $data)
{
parent::__construct($offset,$size,$filename,$be,$data);
$this->cache = $this->cache($data);
$this->type = Arr::get($this->cache,'type');
// For debugging
if (FALSE)
$this->debug = hex_dump($data ?: $this->data());
}
public function __get(string $key): mixed
{
switch ($key) {
case 'audio_samplerate':
case 'video_framerate':
return Arr::get($this->cache,'rate') / Arr::get($this->cache,'scale',1);
case 'audio_codec':
case 'video_codec':
return Arr::get($this->cache,'handler');
case 'duration':
return Arr::get($this->cache,'length');
default:
return parent::__get($key);
}
}
}