wip
This commit is contained in:
parent
1603c45b7a
commit
c3751acb49
7 changed files with 712 additions and 3 deletions
104
HLS/StreamReader.php
Normal file
104
HLS/StreamReader.php
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
<?php
|
||||
/**
|
||||
* Base class for streaming media segment readers
|
||||
*
|
||||
* @file
|
||||
* @ingroup HLS
|
||||
*/
|
||||
|
||||
namespace MediaWiki\TimedMediaHandler\HLS;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Base class for reading/writing a media file with wrappers
|
||||
* for exception handling and possible multi usage.
|
||||
*/
|
||||
class StreamReader {
|
||||
/**
|
||||
* @var resource
|
||||
*/
|
||||
protected $file;
|
||||
|
||||
protected int $pos;
|
||||
|
||||
/**
|
||||
* @param resource $file
|
||||
*/
|
||||
public function __construct( $file ) {
|
||||
if ( get_resource_type( $file ) !== 'stream' ) {
|
||||
throw new Exception( 'Invalid file stream' );
|
||||
}
|
||||
$this->file = $file;
|
||||
$this->pos = $this->tell();
|
||||
}
|
||||
|
||||
private function tell(): int {
|
||||
return ftell( $this->file );
|
||||
}
|
||||
|
||||
public function pos(): int {
|
||||
return $this->pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Seek to given absolute file position.
|
||||
* @throws Exception on error
|
||||
*/
|
||||
public function seek( int $pos ): void {
|
||||
$this->pos = intval( $pos );
|
||||
|
||||
if ( $this->pos === $this->tell() ) {
|
||||
return;
|
||||
}
|
||||
$retval = fseek( $this->file, $this->pos, SEEK_SET );
|
||||
|
||||
if ( $retval < 0 ) {
|
||||
throw new Exception( "Failed to seek to $this->pos bytes" );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read $len bytes or return null on EOF/short read.
|
||||
* @throws Exception on error
|
||||
*/
|
||||
public function read( int $len ): ?string {
|
||||
$this->seek( $this->pos );
|
||||
$bytes = fread( $this->file, $len );
|
||||
if ( $bytes === false ) {
|
||||
throw new Exception( "Read error for $len bytes at $this->pos" );
|
||||
}
|
||||
if ( strlen( $bytes ) < $len ) {
|
||||
return null;
|
||||
}
|
||||
$this->pos += strlen( $bytes );
|
||||
return $bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read exactly $len bytes
|
||||
* @throws Exception on error or short read
|
||||
*/
|
||||
public function readExactly( int $len ): string {
|
||||
$bytes = $this->read( $len );
|
||||
if ( $bytes === null ) {
|
||||
throw new Exception( "Short read for $len bytes at $this->pos" );
|
||||
}
|
||||
return $bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the given data and return number of bytes written.
|
||||
* Short writes are possible on network connections, in theory.
|
||||
* @throws Exception on error
|
||||
*/
|
||||
public function write( string $bytes ): int {
|
||||
$this->seek( $this->pos );
|
||||
$len = strlen( $bytes );
|
||||
$nbytes = fwrite( $this->file, $bytes );
|
||||
if ( $nbytes === false ) {
|
||||
throw new Exception( "Write error for $len bytes at $this->pos" );
|
||||
}
|
||||
return $nbytes;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue