source: extensions/charlies_content/getid3/getid3/module.audio-video.nsv.php @ 3544

Last change on this file since 3544 was 3544, checked in by vdigital, 15 years ago

Change: getid3 upgraded to -> 1.7.9

  • Property svn:keywords set to Author Date Id Revision
File size: 9.4 KB
Line 
1<?php
2/////////////////////////////////////////////////////////////////
3/// getID3() by James Heinrich <info@getid3.org>               //
4//  available at http://getid3.sourceforge.net                 //
5//            or http://www.getid3.org                         //
6/////////////////////////////////////////////////////////////////
7// See readme.txt for more details                             //
8/////////////////////////////////////////////////////////////////
9//                                                             //
10// module.audio.nsv.php                                        //
11// module for analyzing Nullsoft NSV files                     //
12// dependencies: NONE                                          //
13//                                                            ///
14/////////////////////////////////////////////////////////////////
15
16
17class getid3_nsv
18{
19
20        function getid3_nsv(&$fd, &$ThisFileInfo) {
21
22                fseek($fd, $ThisFileInfo['avdataoffset'], SEEK_SET);
23                $NSVheader = fread($fd, 4);
24
25                switch ($NSVheader) {
26                        case 'NSVs':
27                                if ($this->getNSVsHeaderFilepointer($fd, $ThisFileInfo, 0)) {
28                                        $ThisFileInfo['fileformat']          = 'nsv';
29                                        $ThisFileInfo['audio']['dataformat'] = 'nsv';
30                                        $ThisFileInfo['video']['dataformat'] = 'nsv';
31                                        $ThisFileInfo['audio']['lossless']   = false;
32                                        $ThisFileInfo['video']['lossless']   = false;
33                                }
34                                break;
35
36                        case 'NSVf':
37                                if ($this->getNSVfHeaderFilepointer($fd, $ThisFileInfo, 0)) {
38                                        $ThisFileInfo['fileformat']          = 'nsv';
39                                        $ThisFileInfo['audio']['dataformat'] = 'nsv';
40                                        $ThisFileInfo['video']['dataformat'] = 'nsv';
41                                        $ThisFileInfo['audio']['lossless']   = false;
42                                        $ThisFileInfo['video']['lossless']   = false;
43                                        $this->getNSVsHeaderFilepointer($fd, $ThisFileInfo, $ThisFileInfo['nsv']['NSVf']['header_length']);
44                                }
45                                break;
46
47                        default:
48                                $ThisFileInfo['error'][] = 'Expecting "NSVs" or "NSVf" at offset '.$ThisFileInfo['avdataoffset'].', found "'.$NSVheader.'"';
49                                return false;
50                                break;
51                }
52
53                if (!isset($ThisFileInfo['nsv']['NSVf'])) {
54                        $ThisFileInfo['warning'][] = 'NSVf header not present - cannot calculate playtime or bitrate';
55                }
56
57                return true;
58        }
59
60        function getNSVsHeaderFilepointer(&$fd, &$ThisFileInfo, $fileoffset) {
61                fseek($fd, $fileoffset, SEEK_SET);
62                $NSVsheader = fread($fd, 28);
63                $offset = 0;
64
65                $ThisFileInfo['nsv']['NSVs']['identifier']      =                  substr($NSVsheader, $offset, 4);
66                $offset += 4;
67
68                if ($ThisFileInfo['nsv']['NSVs']['identifier'] != 'NSVs') {
69                        $ThisFileInfo['error'][] = 'expected "NSVs" at offset ('.$fileoffset.'), found "'.$ThisFileInfo['nsv']['NSVs']['identifier'].'" instead';
70                        unset($ThisFileInfo['nsv']['NSVs']);
71                        return false;
72                }
73
74                $ThisFileInfo['nsv']['NSVs']['offset']          = $fileoffset;
75
76                $ThisFileInfo['nsv']['NSVs']['video_codec']     =                              substr($NSVsheader, $offset, 4);
77                $offset += 4;
78                $ThisFileInfo['nsv']['NSVs']['audio_codec']     =                              substr($NSVsheader, $offset, 4);
79                $offset += 4;
80                $ThisFileInfo['nsv']['NSVs']['resolution_x']    = getid3_lib::LittleEndian2Int(substr($NSVsheader, $offset, 2));
81                $offset += 2;
82                $ThisFileInfo['nsv']['NSVs']['resolution_y']    = getid3_lib::LittleEndian2Int(substr($NSVsheader, $offset, 2));
83                $offset += 2;
84
85                $ThisFileInfo['nsv']['NSVs']['framerate_index'] = getid3_lib::LittleEndian2Int(substr($NSVsheader, $offset, 1));
86                $offset += 1;
87                //$ThisFileInfo['nsv']['NSVs']['unknown1b']       = getid3_lib::LittleEndian2Int(substr($NSVsheader, $offset, 1));
88                $offset += 1;
89                //$ThisFileInfo['nsv']['NSVs']['unknown1c']       = getid3_lib::LittleEndian2Int(substr($NSVsheader, $offset, 1));
90                $offset += 1;
91                //$ThisFileInfo['nsv']['NSVs']['unknown1d']       = getid3_lib::LittleEndian2Int(substr($NSVsheader, $offset, 1));
92                $offset += 1;
93                //$ThisFileInfo['nsv']['NSVs']['unknown2a']       = getid3_lib::LittleEndian2Int(substr($NSVsheader, $offset, 1));
94                $offset += 1;
95                //$ThisFileInfo['nsv']['NSVs']['unknown2b']       = getid3_lib::LittleEndian2Int(substr($NSVsheader, $offset, 1));
96                $offset += 1;
97                //$ThisFileInfo['nsv']['NSVs']['unknown2c']       = getid3_lib::LittleEndian2Int(substr($NSVsheader, $offset, 1));
98                $offset += 1;
99                //$ThisFileInfo['nsv']['NSVs']['unknown2d']       = getid3_lib::LittleEndian2Int(substr($NSVsheader, $offset, 1));
100                $offset += 1;
101
102                switch ($ThisFileInfo['nsv']['NSVs']['audio_codec']) {
103                        case 'PCM ':
104                                $ThisFileInfo['nsv']['NSVs']['bits_channel'] = getid3_lib::LittleEndian2Int(substr($NSVsheader, $offset, 1));
105                                $offset += 1;
106                                $ThisFileInfo['nsv']['NSVs']['channels']     = getid3_lib::LittleEndian2Int(substr($NSVsheader, $offset, 1));
107                                $offset += 1;
108                                $ThisFileInfo['nsv']['NSVs']['sample_rate']  = getid3_lib::LittleEndian2Int(substr($NSVsheader, $offset, 2));
109                                $offset += 2;
110
111                                $ThisFileInfo['audio']['sample_rate']        = $ThisFileInfo['nsv']['NSVs']['sample_rate'];
112                                break;
113
114                        case 'MP3 ':
115                        case 'NONE':
116                        default:
117                                //$ThisFileInfo['nsv']['NSVs']['unknown3']     = getid3_lib::LittleEndian2Int(substr($NSVsheader, $offset, 4));
118                                $offset += 4;
119                                break;
120                }
121
122                $ThisFileInfo['video']['resolution_x']       = $ThisFileInfo['nsv']['NSVs']['resolution_x'];
123                $ThisFileInfo['video']['resolution_y']       = $ThisFileInfo['nsv']['NSVs']['resolution_y'];
124                $ThisFileInfo['nsv']['NSVs']['frame_rate']   = $this->NSVframerateLookup($ThisFileInfo['nsv']['NSVs']['framerate_index']);
125                $ThisFileInfo['video']['frame_rate']         = $ThisFileInfo['nsv']['NSVs']['frame_rate'];
126                $ThisFileInfo['video']['bits_per_sample']    = 24;
127                $ThisFileInfo['video']['pixel_aspect_ratio'] = (float) 1;
128
129                return true;
130        }
131
132        function getNSVfHeaderFilepointer(&$fd, &$ThisFileInfo, $fileoffset, $getTOCoffsets=false) {
133                fseek($fd, $fileoffset, SEEK_SET);
134                $NSVfheader = fread($fd, 28);
135                $offset = 0;
136
137                $ThisFileInfo['nsv']['NSVf']['identifier']    =                  substr($NSVfheader, $offset, 4);
138                $offset += 4;
139
140                if ($ThisFileInfo['nsv']['NSVf']['identifier'] != 'NSVf') {
141                        $ThisFileInfo['error'][] = 'expected "NSVf" at offset ('.$fileoffset.'), found "'.$ThisFileInfo['nsv']['NSVf']['identifier'].'" instead';
142                        unset($ThisFileInfo['nsv']['NSVf']);
143                        return false;
144                }
145
146                $ThisFileInfo['nsv']['NSVs']['offset']        = $fileoffset;
147
148                $ThisFileInfo['nsv']['NSVf']['header_length'] = getid3_lib::LittleEndian2Int(substr($NSVfheader, $offset, 4));
149                $offset += 4;
150                $ThisFileInfo['nsv']['NSVf']['file_size']     = getid3_lib::LittleEndian2Int(substr($NSVfheader, $offset, 4));
151                $offset += 4;
152
153                if ($ThisFileInfo['nsv']['NSVf']['file_size'] > $ThisFileInfo['avdataend']) {
154                        $ThisFileInfo['warning'][] = 'truncated file - NSVf header indicates '.$ThisFileInfo['nsv']['NSVf']['file_size'].' bytes, file actually '.$ThisFileInfo['avdataend'].' bytes';
155                }
156
157                $ThisFileInfo['nsv']['NSVf']['playtime_ms']   = getid3_lib::LittleEndian2Int(substr($NSVfheader, $offset, 4));
158                $offset += 4;
159                $ThisFileInfo['nsv']['NSVf']['meta_size']     = getid3_lib::LittleEndian2Int(substr($NSVfheader, $offset, 4));
160                $offset += 4;
161                $ThisFileInfo['nsv']['NSVf']['TOC_entries_1'] = getid3_lib::LittleEndian2Int(substr($NSVfheader, $offset, 4));
162                $offset += 4;
163                $ThisFileInfo['nsv']['NSVf']['TOC_entries_2'] = getid3_lib::LittleEndian2Int(substr($NSVfheader, $offset, 4));
164                $offset += 4;
165
166                if ($ThisFileInfo['nsv']['NSVf']['playtime_ms'] == 0) {
167                        $ThisFileInfo['error'][] = 'Corrupt NSV file: NSVf.playtime_ms == zero';
168                        return false;
169                }
170
171                $NSVfheader .= fread($fd, $ThisFileInfo['nsv']['NSVf']['meta_size'] + (4 * $ThisFileInfo['nsv']['NSVf']['TOC_entries_1']) + (4 * $ThisFileInfo['nsv']['NSVf']['TOC_entries_2']));
172                $NSVfheaderlength = strlen($NSVfheader);
173                $ThisFileInfo['nsv']['NSVf']['metadata']      =                  substr($NSVfheader, $offset, $ThisFileInfo['nsv']['NSVf']['meta_size']);
174                $offset += $ThisFileInfo['nsv']['NSVf']['meta_size'];
175
176                if ($getTOCoffsets) {
177                        $TOCcounter = 0;
178                        while ($TOCcounter < $ThisFileInfo['nsv']['NSVf']['TOC_entries_1']) {
179                                if ($TOCcounter < $ThisFileInfo['nsv']['NSVf']['TOC_entries_1']) {
180                                        $ThisFileInfo['nsv']['NSVf']['TOC_1'][$TOCcounter] = getid3_lib::LittleEndian2Int(substr($NSVfheader, $offset, 4));
181                                        $offset += 4;
182                                        $TOCcounter++;
183                                }
184                        }
185                }
186
187                if (trim($ThisFileInfo['nsv']['NSVf']['metadata']) != '') {
188                        $ThisFileInfo['nsv']['NSVf']['metadata'] = str_replace('`', "\x01", $ThisFileInfo['nsv']['NSVf']['metadata']);
189                        $CommentPairArray = explode("\x01".' ', $ThisFileInfo['nsv']['NSVf']['metadata']);
190                        foreach ($CommentPairArray as $CommentPair) {
191                                if (strstr($CommentPair, '='."\x01")) {
192                                        list($key, $value) = explode('='."\x01", $CommentPair, 2);
193                                        $ThisFileInfo['nsv']['comments'][strtolower($key)][] = trim(str_replace("\x01", '', $value));
194                                }
195                        }
196                }
197
198                $ThisFileInfo['playtime_seconds'] = $ThisFileInfo['nsv']['NSVf']['playtime_ms'] / 1000;
199                $ThisFileInfo['bitrate']          = ($ThisFileInfo['nsv']['NSVf']['file_size'] * 8) / $ThisFileInfo['playtime_seconds'];
200
201                return true;
202        }
203
204
205        function NSVframerateLookup($framerateindex) {
206                if ($framerateindex <= 127) {
207                        return (float) $framerateindex;
208                }
209
210                static $NSVframerateLookup = array();
211                if (empty($NSVframerateLookup)) {
212                        $NSVframerateLookup[129] = (float) 29.970;
213                        $NSVframerateLookup[131] = (float) 23.976;
214                        $NSVframerateLookup[133] = (float) 14.985;
215                        $NSVframerateLookup[197] = (float) 59.940;
216                        $NSVframerateLookup[199] = (float) 47.952;
217                }
218                return (isset($NSVframerateLookup[$framerateindex]) ? $NSVframerateLookup[$framerateindex] : false);
219        }
220
221}
222
223
224?>
Note: See TracBrowser for help on using the repository browser.