21 {
22 $info = &$this->getid3->info;
23
25
26 $ShortenHeader = $this->
fread(8);
27 $magic = 'ajkg';
28 if (substr($ShortenHeader, 0, 4) != $magic) {
30 return false;
31 }
32 $info[
'fileformat'] =
'shn';
33 $info[
'audio'][
'dataformat'] =
'shn';
34 $info[
'audio'][
'lossless'] =
true;
35 $info[
'audio'][
'bitrate_mode'] =
'vbr';
36
38
40 $SeekTableSignatureTest = $this->
fread(12);
41 $info[
'shn'][
'seektable'][
'present'] = (bool) (substr($SeekTableSignatureTest, 4, 8) ==
'SHNAMPSK');
42 if (
$info[
'shn'][
'seektable'][
'present']) {
44 $info[
'shn'][
'seektable'][
'offset'] =
$info[
'avdataend'] -
$info[
'shn'][
'seektable'][
'length'];
45 $this->
fseek($info[
'shn'][
'seektable'][
'offset']);
46 $SeekTableMagic = $this->
fread(4);
47 $magic = 'SEEK';
48 if ($SeekTableMagic != $magic) {
49
51 return false;
52
53 } else {
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71 $SeekTableData = $this->
fread($info[
'shn'][
'seektable'][
'length'] - 16);
72 $info[
'shn'][
'seektable'][
'entry_count'] = floor(strlen($SeekTableData) / 80);
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 if (preg_match('#(1|ON)#i', ini_get('safe_mode'))) {
117 $this->
error(
'PHP running in Safe Mode - backtick operator not available, cannot run shntool to analyze Shorten files');
118 return false;
119 }
120
121 if (GETID3_OS_ISWINDOWS) {
122
123 $RequiredFiles = array('shorten.exe', 'cygwin1.dll', 'head.exe');
124 foreach ($RequiredFiles as $required_file) {
125 if (!is_readable(GETID3_HELPERAPPSDIR.$required_file)) {
126 $this->
error(GETID3_HELPERAPPSDIR.$required_file.
' does not exist');
127 return false;
128 }
129 }
130 $commandline = GETID3_HELPERAPPSDIR.
'shorten.exe -x "'.
$info[
'filenamepath'].
'" - | '.GETID3_HELPERAPPSDIR.
'head.exe -c 64';
131 $commandline = str_replace('/', '\\', $commandline);
132
133 } else {
134
135 static $shorten_present;
136 if (!isset($shorten_present)) {
137 $shorten_present = file_exists('/usr/local/bin/shorten') || `which shorten`;
138 }
139 if (!$shorten_present) {
140 $this->
error(
'shorten binary was not found in path or /usr/local/bin');
141 return false;
142 }
143 $commandline = (file_exists(
'/usr/local/bin/shorten') ?
'/usr/local/bin/' :
'' ) .
'shorten -x '.escapeshellarg(
$info[
'filenamepath']).
' - | head -c 64';
144
145 }
146
148
150
152
155 $info[
'audio'][
'channels'] = $DecodedWAVFORMATEX[
'channels'];
156 $info[
'audio'][
'bits_per_sample'] = $DecodedWAVFORMATEX[
'bits_per_sample'];
157 $info[
'audio'][
'sample_rate'] = $DecodedWAVFORMATEX[
'sample_rate'];
158
159 if (substr(
$output, 20 + $fmt_size, 4) ==
'data') {
160
162
163 } else {
164
165 $this->
error(
'shorten failed to decode DATA chunk to expected location, cannot determine playtime');
166 return false;
167
168 }
169
170 $info[
'audio'][
'bitrate'] = ((
$info[
'avdataend'] -
$info[
'avdataoffset']) /
$info[
'playtime_seconds']) * 8;
171
172 } else {
173
174 $this->
error(
'shorten failed to decode file to WAV for parsing');
175 return false;
176
177 }
178
179 return true;
180 }
fseek($bytes, $whence=SEEK_SET)
static PrintHexBytes($string, $hex=true, $spaces=true, $htmlencoding='UTF-8')
static LittleEndian2Int($byteword, $signed=false)
static IncludeDependency($filename, $sourcefile, $DieOnFailure=false)
static parseWAVEFORMATex($WaveFormatExData)