Last active
July 15, 2020 18:26
-
-
Save d4rkne55/91843ee8ffc070ed7f1c7bf6b2bd3974 to your computer and use it in GitHub Desktop.
Class with some calculations and informations for media files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class Media | |
{ | |
public $calcBase = 1024; | |
public $fileSize = 0; | |
public $sizePrefixes = array( | |
1000 => array( | |
'', | |
'K', | |
'M', | |
'G', | |
'T' | |
), | |
1024 => array( | |
'', | |
'Ki', | |
'Mi', | |
'Gi', | |
'Ti' | |
) | |
); | |
public function getFileSize($precision = 2) { | |
$size = $this->fileSize; | |
$base = $this->calcBase; | |
for ($i = 0; $size >= $base; $i++) { | |
$size /= $base; | |
} | |
$size = round($size, $precision); | |
$sizeStr = "$size " . $this->sizePrefixes[$base][$i] . 'B'; | |
return $sizeStr; | |
} | |
public static function parseFileSize($sizeStr) { | |
$prefixMulti = array( | |
'k' => 2**10, | |
'm' => 2**20, | |
'g' => 2**30, | |
't' => 2**40 | |
); | |
preg_match('/[a-z]/i', $sizeStr, $prefix); | |
$prefix = !empty($prefix) ? lcfirst($prefix[0]) : ''; | |
$sizeFloat = (float) strtr($sizeStr, ',', '.'); | |
if (array_key_exists($prefix, $prefixMulti)) { | |
$sizeFloat *= $prefixMulti[$prefix]; | |
} | |
return ceil($sizeFloat); | |
} | |
public static function parseTime($timeStr) { | |
$times = explode(':', $timeStr); | |
$seconds = 0; | |
foreach (array_reverse($times) as $i => $time) { | |
$seconds += $time * 60**$i; | |
} | |
return $seconds; | |
} | |
} | |
class Image extends Media | |
{ | |
public $width; | |
public $height; | |
public $pixelDepth; | |
public function __construct($width, $height, $pixelDepth = 24) { | |
$this->width = (int) $width; | |
$this->height = (int) $height; | |
$this->pixelDepth = $pixelDepth; | |
$this->calcFileSize(); | |
} | |
protected function calcFileSize() { | |
$this->fileSize = $this->width * $this->height * $this->pixelDepth / 8; | |
} | |
} | |
class Audio extends Media | |
{ | |
public $length; | |
public $bitrate; | |
public $channels; | |
public $samplingRate; | |
public $bitDepth; | |
public function __construct($length, $bitrateKbps = 0, $channels = 2, $samplingRate = 44100, $bitDepth = 16) { | |
$this->length = parent::parseTime($length); | |
$this->bitrate = $bitrateKbps * 1000; | |
$this->channels = $channels; | |
$this->samplingRate = $samplingRate; | |
$this->bitDepth = $bitDepth; | |
if (is_string($channels)) { | |
$this->channels = (int) array_sum(explode('.', $channels)); | |
} | |
// calculate uncompressed bitrate when not given | |
if ($bitrateKbps == 0) { | |
$this->bitrate = $this->samplingRate * $this->bitDepth * $this->channels; | |
} | |
$this->calcFileSize(); | |
} | |
public function setBitrate($bitrateKbps) { | |
$this->bitrate = $bitrateKbps * 1000; | |
} | |
public function getBitrate() { | |
return $this->bitrate / 1000; | |
} | |
protected function calcFileSize() { | |
$this->fileSize = $this->length * $this->bitrate / 8; | |
} | |
} | |
class Video extends Media | |
{ | |
public $length; | |
public $bitrate; | |
public $framerate; | |
public $width; | |
public $height; | |
public function __construct($length, $bitrateKbps, $width = null, $height = null, $framerate = 23.976) { | |
$this->length = parent::parseTime($length); | |
$this->bitrate = $bitrateKbps * 1000; | |
$this->framerate = $framerate; | |
$this->width = (int) $width; | |
$this->height = (int) $height; | |
$this->calcFileSize(); | |
} | |
public function setBitrate($bitrateKbps) { | |
$this->bitrate = $bitrateKbps * 1000; | |
} | |
public function getBitrate() { | |
return $this->bitrate / 1000; | |
} | |
public function getQualityFactor() { | |
$qf = $this->bitrate / ($this->width * $this->height * $this->framerate); | |
return sprintf('%.3f', $qf); | |
} | |
public function calcBitrateForQf($qualityFactor) { | |
$bitrate = $qualityFactor * $this->width * $this->height * $this->framerate; | |
return round($bitrate / 1000); | |
} | |
public function calcBitrateForSize($fileSize) { | |
if (is_string($fileSize)) { | |
$fileSize = parent::parseFileSize($fileSize); | |
} | |
$bitrate = $fileSize / $this->length * 8; | |
return round($bitrate / 1000); | |
} | |
public function getAspectRatio() { | |
return round($this->width / $this->height, 2); | |
} | |
public static function calcMaxRefs($width, $height, $profileLevel) { | |
$maxDPB = array( | |
'1' => 396, | |
'1.1' => 900, | |
'1.2' => 2376, | |
'1.3' => 2376, | |
'2' => 2376, | |
'2.1' => 4752, | |
'2.2' => 8100, | |
'3' => 8100, | |
'3.1' => 18000, | |
'3.2' => 20480, | |
'4' => 32768, | |
'4.1' => 32768, | |
'4.2' => 34816, | |
'5' => 110400, | |
'5.1' => 184320, | |
'5.2' => 184320 | |
); | |
if (!array_key_exists($profileLevel, $maxDPB)) { | |
throw new InvalidArgumentException("Given profile level doesn't exist!"); | |
} | |
$maxDPB = $maxDPB[$profileLevel]; | |
// macroblock counts | |
$horMbs = ($width + ($width % 16)) / 16; | |
$vertMbs = ($height + ($height % 16)) / 16; | |
$maxRefs = (int) floor($maxDPB / ($horMbs * $vertMbs)); | |
return min($maxRefs, 16); | |
} | |
protected function calcFileSize() { | |
$this->fileSize = $this->length * $this->bitrate / 8; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment