Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 51 |
|
0.00% |
0 / 7 |
CRAP | |
0.00% |
0 / 1 |
MP4Handler | |
0.00% |
0 / 51 |
|
0.00% |
0 / 7 |
462 | |
0.00% |
0 / 1 |
getID3 | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
getImageSize | |
0.00% |
0 / 11 |
|
0.00% |
0 / 1 |
30 | |||
getMetadataType | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getWebType | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getStreamTypes | |
0.00% |
0 / 12 |
|
0.00% |
0 / 1 |
90 | |||
getShortDesc | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
6 | |||
getLongDesc | |
0.00% |
0 / 16 |
|
0.00% |
0 / 1 |
6 |
1 | <?php |
2 | |
3 | namespace MediaWiki\TimedMediaHandler\Handlers\MP4Handler; |
4 | |
5 | use File; |
6 | use MediaWiki\TimedMediaHandler\Handlers\ID3Handler\ID3Handler; |
7 | |
8 | /** |
9 | * MP4 handler |
10 | */ |
11 | class MP4Handler extends ID3Handler { |
12 | |
13 | /** |
14 | * @param string $path |
15 | * @return array |
16 | */ |
17 | protected function getID3( $path ) { |
18 | $id3 = parent::getID3( $path ); |
19 | // Unset some parts of id3 that are too detailed and matroska specific: |
20 | unset( $id3['quicktime'] ); |
21 | return $id3; |
22 | } |
23 | |
24 | /** |
25 | * Get the "media size" |
26 | * @param File $file |
27 | * @param string $path |
28 | * @param string|false $metadata |
29 | * @return array|false |
30 | */ |
31 | public function getImageSize( $file, $path, $metadata = false ) { |
32 | // Just return the size of the first video stream |
33 | if ( $metadata === false ) { |
34 | $metadata = $file->getMetadata(); |
35 | } |
36 | $metadata = $this->unpackMetadata( $metadata ); |
37 | if ( isset( $metadata['error'] ) ) { |
38 | return false; |
39 | } |
40 | if ( isset( $metadata['video']['resolution_x'] ) && isset( $metadata['video']['resolution_y'] ) ) { |
41 | return [ |
42 | $metadata['video']['resolution_x'], |
43 | $metadata['video']['resolution_y'] |
44 | ]; |
45 | } |
46 | return [ false, false ]; |
47 | } |
48 | |
49 | /** |
50 | * @param File $image |
51 | * @return string |
52 | */ |
53 | public function getMetadataType( $image ) { |
54 | return 'mp4'; |
55 | } |
56 | |
57 | /** |
58 | * @param File $file |
59 | * @return string |
60 | */ |
61 | public function getWebType( $file ) { |
62 | // phpcs:disable Generic.Files.LineLength |
63 | /** |
64 | * h.264 profile types: |
65 | * H.264 Simple baseline profile video (main and extended video compatible) level 3 and Low-Complexity AAC audio in MP4 container: |
66 | * type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"' |
67 | * |
68 | * H.264 Extended profile video (baseline-compatible) level 3 and Low-Complexity AAC audio in MP4 container: |
69 | * type='video/mp4; codecs="avc1.58A01E, mp4a.40.2"' |
70 | * |
71 | * H.264 Main profile video level 3 and Low-Complexity AAC audio in MP4 container |
72 | * type='video/mp4; codecs="avc1.4D401E, mp4a.40.2"' |
73 | * |
74 | * H.264 ‘High’ profile video (incompatible with main, baseline, or extended profiles) level 3 and Low-Complexity AAC audio in MP4 container |
75 | * type='video/mp4; codecs="avc1.64001E, mp4a.40.2"' |
76 | */ |
77 | // phpcs:enable |
78 | // all h.264 encodes are currently simple profile |
79 | return 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"'; |
80 | } |
81 | |
82 | /** |
83 | * @param File $file |
84 | * @return string[]|false |
85 | */ |
86 | public function getStreamTypes( $file ) { |
87 | $streamTypes = []; |
88 | $metadata = $this->unpackMetadata( $file->getMetadata() ); |
89 | if ( !$metadata || isset( $metadata['error'] ) ) { |
90 | return false; |
91 | } |
92 | if ( isset( $metadata['audio'] ) && $metadata['audio']['dataformat'] === 'mp4' ) { |
93 | if ( isset( $metadata['audio']['codec'] ) |
94 | && |
95 | strpos( $metadata['audio']['codec'], 'AAC' ) !== false |
96 | ) { |
97 | $streamTypes[] = 'AAC'; |
98 | } else { |
99 | $streamTypes[] = $metadata['audio']['codec']; |
100 | } |
101 | } |
102 | // id3 gives 'V_VP8' for what we call VP8 |
103 | if ( isset( $metadata['video'] ) && $metadata['video']['dataformat'] === 'quicktime' ) { |
104 | $streamTypes[] = 'h.264'; |
105 | } |
106 | |
107 | return $streamTypes; |
108 | } |
109 | |
110 | /** |
111 | * @param File $file |
112 | * @return string |
113 | */ |
114 | public function getShortDesc( $file ) { |
115 | $streamTypes = $this->getStreamTypes( $file ); |
116 | if ( !$streamTypes ) { |
117 | return parent::getShortDesc( $file ); |
118 | } |
119 | return wfMessage( 'timedmedia-mp4-short-video', implode( '/', $streamTypes ) |
120 | )->timeperiodParams( |
121 | $this->getLength( $file ) |
122 | )->text(); |
123 | } |
124 | |
125 | /** |
126 | * @param File $file |
127 | * @return string |
128 | */ |
129 | public function getLongDesc( $file ) { |
130 | $streamTypes = $this->getStreamTypes( $file ); |
131 | if ( !$streamTypes ) { |
132 | return parent::getLongDesc( $file ); |
133 | } |
134 | return wfMessage( |
135 | 'timedmedia-mp4-long-video', |
136 | implode( '/', $streamTypes ) |
137 | )->timeperiodParams( |
138 | $this->getLength( $file ) |
139 | )->bitrateParams( |
140 | $this->getBitRate( $file ) |
141 | )->numParams( |
142 | $file->getWidth(), |
143 | $file->getHeight() |
144 | )->sizeParams( |
145 | $file->getSize() |
146 | )->text(); |
147 | } |
148 | |
149 | } |