summaryrefslogtreecommitdiff
path: root/extensions/TimedMediaHandler/handlers/Mp4Handler/Mp4Handler.php
blob: 897e10174f56be0262fb7fe10f149ba0d69722db (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
<?php
/**
 * MP4 handler
 */
class Mp4Handler extends ID3Handler {

	/**
	 * @param $path string
	 * @return array
	 */
	protected function getID3( $path ) {
		$id3 = parent::getID3( $path );
		// Unset some parts of id3 that are too detailed and matroska specific:
		unset( $id3['quicktime'] );
		return $id3;
	}

	/**
	 * Get the "media size"
	 * @param $file File
	 * @param $path string
	 * @param $metadata bool
	 * @return array|bool
	 */
	function getImageSize( $file, $path, $metadata = false ) {
		// Just return the size of the first video stream
		if ( $metadata === false ) {
			$metadata = $file->getMetadata();
		}
		$metadata = $this->unpackMetadata( $metadata );
		if ( isset( $metadata['error'] ) ) {
			return false;
		}
		if( isset( $metadata['video']['resolution_x'])
				&&
			isset( $metadata['video']['resolution_y'])
		){
			return array (
				$metadata['video']['resolution_x'],
				$metadata['video']['resolution_y']
			);
		}
		return array( false, false );
	}

	/**
	 * @param $image
	 * @return string
	 */
	function getMetadataType( $image ) {
		return 'mp4';
	}
	/**
	 * @param $file File
	 */
	function getWebType( $file ) {
		/**
		 * h.264 profile types:
			H.264 Simple baseline profile video (main and extended video compatible) level 3 and Low-Complexity AAC audio in MP4 container:
			type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'

			H.264 Extended profile video (baseline-compatible) level 3 and Low-Complexity AAC audio in MP4 container:
			type='video/mp4; codecs="avc1.58A01E, mp4a.40.2"'

			H.264 Main profile video level 3 and Low-Complexity AAC audio in MP4 container
			type='video/mp4; codecs="avc1.4D401E, mp4a.40.2"'

			H.264 ‘High’ profile video (incompatible with main, baseline, or extended profiles) level 3 and Low-Complexity AAC audio in MP4 container
			type='video/mp4; codecs="avc1.64001E, mp4a.40.2"'
		 */
		// all h.264 encodes are currently simple profile
		return 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';
	}
	/**
	 * @param $file File
	 * @return array|bool
	 */
	function getStreamTypes( $file ) {
		$streamTypes = array();
		$metadata = self::unpackMetadata( $file->getMetadata() );
		if ( !$metadata || isset( $metadata['error'] ) ) {
			return false;
		}
		if( isset( $metadata['audio'] ) && $metadata['audio']['dataformat'] == 'mp4' ){
			if( isset( $metadata['audio']['codec'] )
				&&
				strpos( $metadata['audio']['codec'] , 'AAC' ) !== false
			){
				$streamTypes[] =  'AAC';
			} else {
				$streamTypes[] = $metadata['audio']['codec'];
			}
		}
		// id3 gives 'V_VP8' for what we call VP8
		if( $metadata['video']['dataformat'] == 'quicktime' ){
			$streamTypes[] =  'h.264';
		}

		return $streamTypes;
	}

	/**
	 * @param $file File
	 * @return String
	 */
	function getShortDesc( $file ) {
		$streamTypes = $this->getStreamTypes( $file );
		if ( !$streamTypes ) {
			return parent::getShortDesc( $file );
		}
		return wfMessage( 'timedmedia-mp4-short-video', implode( '/', $streamTypes )
		)->timeperiodParams(
			$this->getLength( $file )
		)->text();
	}

	/**
	 * @param $file File
	 * @return String
	 */
	function getLongDesc( $file ) {
		$streamTypes = $this->getStreamTypes( $file );
		if ( !$streamTypes ) {
			return parent::getLongDesc( $file );
		}
		return wfMessage('timedmedia-mp4-long-video',
			implode( '/', $streamTypes )
		)->timeperiodParams(
			$this->getLength( $file )
		)->bitrateParams(
			$this->getBitRate( $file )
		)->numParams(
			$file->getWidth(),
			$file->getHeight()
		)->text();

	}

}