40 {
41 $info = &$this->getid3->info;
42
43 fseek($this->getid3->fp,
$info[
'avdataoffset'], SEEK_SET);
44
45 $ShortenHeader =
fread($this->getid3->fp, 8);
46 $magic = 'ajkg';
47 if (substr($ShortenHeader, 0, 4) != $magic) {
48 $info[
'error'][] =
'Expecting "'.Helper::PrintHexBytes($magic).
'" at offset '.
$info[
'avdataoffset'].
', found "'.
Helper::PrintHexBytes(substr($ShortenHeader, 0, 4)).
'"';
49
50 return false;
51 }
52 $info[
'fileformat'] =
'shn';
53 $info[
'audio'][
'dataformat'] =
'shn';
54 $info[
'audio'][
'lossless'] =
true;
55 $info[
'audio'][
'bitrate_mode'] =
'vbr';
56
58
59 fseek($this->getid3->fp,
$info[
'avdataend'] - 12, SEEK_SET);
60 $SeekTableSignatureTest =
fread($this->getid3->fp, 12);
61 $info[
'shn'][
'seektable'][
'present'] = (bool) (substr($SeekTableSignatureTest, 4, 8) ==
'SHNAMPSK');
62 if (
$info[
'shn'][
'seektable'][
'present']) {
64 $info[
'shn'][
'seektable'][
'offset'] =
$info[
'avdataend'] -
$info[
'shn'][
'seektable'][
'length'];
65 fseek($this->getid3->fp,
$info[
'shn'][
'seektable'][
'offset'], SEEK_SET);
66 $SeekTableMagic =
fread($this->getid3->fp, 4);
67 $magic = 'SEEK';
68 if ($SeekTableMagic != $magic) {
69
70 $info[
'error'][] =
'Expecting "'.Helper::PrintHexBytes($magic).
'" at offset '.
$info[
'shn'][
'seektable'][
'offset'].
', found "'.
Helper::PrintHexBytes($SeekTableMagic).
'"';
71
72 return false;
73
74 } else {
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92 $SeekTableData =
fread($this->getid3->fp,
$info[
'shn'][
'seektable'][
'length'] - 16);
93 $info[
'shn'][
'seektable'][
'entry_count'] = floor(strlen($SeekTableData) / 80);
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 if (preg_match('#(1|ON)#i', ini_get('safe_mode'))) {
138 $info[
'error'][] =
'PHP running in Safe Mode - backtick operator not available, cannot run shntool to analyze Shorten files';
139
140 return false;
141 }
142
144
145 $RequiredFiles = array('shorten.exe', 'cygwin1.dll', 'head.exe');
146 foreach ($RequiredFiles as $required_file) {
149
150 return false;
151 }
152 }
154 $commandline = str_replace('/', '\\', $commandline);
155
156 } else {
157
158 static $shorten_present;
159 if (!isset($shorten_present)) {
160 $shorten_present = file_exists('/usr/local/bin/shorten') || `which shorten`;
161 }
162 if (!$shorten_present) {
163 $info[
'error'][] =
'shorten binary was not found in path or /usr/local/bin';
164
165 return false;
166 }
167 $commandline = (file_exists(
'/usr/local/bin/shorten') ?
'/usr/local/bin/' :
'' ) .
'shorten -x '.escapeshellarg(
$info[
'filenamepath']).
' - | head -c 64';
168
169 }
170
172
174
177 $info[
'audio'][
'channels'] = $DecodedWAVFORMATEX[
'channels'];
178 $info[
'audio'][
'bits_per_sample'] = $DecodedWAVFORMATEX[
'bits_per_sample'];
179 $info[
'audio'][
'sample_rate'] = $DecodedWAVFORMATEX[
'sample_rate'];
180
181 if (substr(
$output, 20 + $fmt_size, 4) ==
'data') {
182
184
185 } else {
186
187 $info[
'error'][] =
'shorten failed to decode DATA chunk to expected location, cannot determine playtime';
188
189 return false;
190
191 }
192
193 $info[
'audio'][
'bitrate'] = ((
$info[
'avdataend'] -
$info[
'avdataoffset']) /
$info[
'playtime_seconds']) * 8;
194
195 } else {
196
197 $info[
'error'][] =
'shorten failed to decode file to WAV for parsing';
198
199 return false;
200
201 }
202
203 return true;
204 }
static environmentIsWindows()
static getHelperAppsDir()
fseek($bytes, $whence=SEEK_SET)
static LittleEndian2Int($byteword, $signed=false)
static PrintHexBytes($string, $hex=true, $spaces=true, $htmlencoding='UTF-8')
static RIFFparseWAVEFORMATex($WaveFormatExData)
if(!is_dir( $entity_dir)) exit("Fatal Error ([A-Za-z0-9]+)\s+" &#(? foreach( $entity_files as $file) $output