MediaInfoHelper::hasMediaInfo()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 2
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 4
rs 10
1
<?php
2
3
/**
4
 * Helper class for determining media information, such as what codecs it uses 
5
 * etc.
6
 *
7
 * @author Sam Stenvall <[email protected]>
8
 * @copyright Copyright &copy; Sam Stenvall 2013-
9
 * @license https://www.gnu.org/licenses/gpl.html The GNU General Public License v3.0
10
 */
11
class MediaInfoHelper
12
{
13
14
	const VIDEO_CODEC_AVC1 = 'avc1';
15
	const VIDEO_CODEC_H264 = 'h264';
16
	const AUDIO_CODEC_AAC = 'aac';
17
	const CONTAINER_MKV = 'mkv';
18
	const CONTAINER_MP4 = 'mp4';
19
	
20
	/**
21
	 * @var array list of codecs that are supported by major browsers
22
	 */
23
	private static $nativeVideoCodecs = array(
24
		self::VIDEO_CODEC_AVC1,
25
		self::VIDEO_CODEC_H264
26
	);
27
	
28
	/**
29
	 * @var array list of container types that are supported by major browsers
30
	 */
31
	private static $nativeContainers = array(
32
		self::CONTAINER_MKV, // Chrome only
33
		self::CONTAINER_MP4,
34
	);
35
	
36
	/**
37
	 * @var array list of file extension that cannot be streamed
38
	 */
39
	private static $nonStreamableExtension = array(
40
		'iso', 'img', 'bdmv', 'ifo',
41
	);
42
	
43
	/**
44
	 * @var File the media file
45
	 */
46
	private $_file;
47
	
48
	/**
49
	 * Class constructor
50
	 * @param File $file the media file
51
	 */
52
	public function __construct($file)
53
	{
54
		$this->_file = $file;
55
	}
56
57
	/**
58
	 * Checks whether the specified will need transcoding in order to be 
59
	 * playable in browsers. For now it assumes that all H.264/AAC/MP4 files 
60
	 * are playable directly, which is not strictly true.
61
	 * @return boolean whether the file needs transcoding
62
	 */
63
	public function needsTranscoding()
64
	{
65
		// If stream details aren't available we'll just have to go on the 
66
		// file extension
67
		if (!$this->hasMediaInfo())
68
			return !$this->hasNativeContainer();
69
70
		$videoCodec = $this->_file->streamdetails->video[0]->codec;
71
		$audioCodec = $this->_file->streamdetails->audio[0]->codec;
72
73
		return !($this->hasNativeContainer() &&
74
				in_array($videoCodec, self::$nativeVideoCodecs) &&
75
				$audioCodec === self::AUDIO_CODEC_AAC);
76
	}
77
78
	/**
79
	 * Checks whether the stream details contain the necessary media info
80
	 * @return boolean
81
	 */
82
	public function hasMediaInfo()
83
	{
84
		return count($this->_file->streamdetails->audio) !== 0 &&
85
			   count($this->_file->streamdetails->video) !== 0;
86
	}
87
	
88
	/**
89
	 * Checks whether the current file is streamable. All files are streamable 
90
	 * except DVD and BluRay images (or folder structures)
91
	 * @return boolean whether the file is streamable
92
	 */
93
	public function isStreamable()
94
	{
95
		foreach ($this->_file->getItemLinks() as $link)
96
		{
97
			// Compare the extension against the blacklist
98
			$fileInfo = new SplFileInfo($link->url);
99
			$extension = strtolower($fileInfo->getExtension());
100
101
			if (in_array($extension, self::$nonStreamableExtension))
102
				return false;
103
		}
104
105
		return true;
106
	}
107
108
	/**
109
	 * @return boolean whether the file uses a container that browsers can 
110
	 * generally play natively
111
	 */
112
	private function hasNativeContainer()
113
	{
114
		$fileInfo = new SplFileInfo($this->_file->file);
115
		return in_array($fileInfo->getExtension(), self::$nativeContainers);
116
	}
117
118
	/**
119
	 * Returns the MIME type of the specified file
120
	 * @param string $file filename or URL
121
	 * @return string the MIME type, or null if it could not be determined
122
	 */
123
	public static function getMIMEType($file)
124
	{
125
		$fileInfo = new SplFileInfo($file);
126
		
127
		switch ($fileInfo->getExtension())
128
		{
129
			case self::CONTAINER_MP4:
130
				return 'video/mp4';
131
			// Ignore MKV on purpose, Chrome refuses to play MKV files when 
132
			// MIME type is set
133
		}
134
		
135
		return null;
136
	}
137
138
}
139