File: asf.t

package info (click to toggle)
libaudio-scan-perl 0.93%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 6,152 kB
  • sloc: ansic: 11,482; perl: 241; sh: 48; makefile: 2
file content (359 lines) | stat: -rw-r--r-- 14,047 bytes parent folder | download | duplicates (3)
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
use strict;

use File::Spec::Functions;
use FindBin ();
use Test::More tests => 142;

use Audio::Scan;

# TODO: LSL_MULT5 profile test (lossless, channels > 2)

my $HAS_ENCODE;
eval {
    require Encode;
    $HAS_ENCODE = 1;
};

# Basic tests of all fields
{
    my $s = Audio::Scan->scan( _f('wma92-32k.wma'), { md5_size => 4096 } );
    
    my $info = $s->{info};
    my $tags = $s->{tags};
    
    is( $info->{audio_offset}, 5161, 'Audio offset ok' );
    is( $info->{audio_size}, 7590, 'Audio size ok' );
    is( $info->{audio_md5}, '472091bc205bf78e0d321b8ef11f2f1c', 'Audio MD5 ok' );
    is( $info->{broadcast}, 0, 'Broadcast not set ok' );
    is( ref $info->{codec_list}, 'ARRAY', 'Codec list ok' );
    is( $info->{codec_list}->[0]->{description}, ' 32 kbps, 22 kHz, stereo 2-pass CBR', 'Codec description ok' );
    is( $info->{codec_list}->[0]->{name}, 'Windows Media Audio 9.2', 'Codec name ok' );
    is( $info->{codec_list}->[0]->{type}, 'Audio', 'Codec type ok' );
    is( $info->{creation_date}, 1239379533, 'Creation date ok' );
    is( $info->{data_packets}, 5, 'Data packets ok' );
    is( $info->{file_id}, '4c2d71e7-f116-4e47-ae0f-e27a4632f9e3', 'File ID ok' );
    is( $info->{file_size}, 12751, 'File size ok' );
    is( ref $info->{language_list}, 'ARRAY', 'Language list ok' );
    is( $info->{language_list}->[0], 'en-us', 'Language list item ok' );
    is( $info->{max_bitrate}, 32645, 'Max bitrate ok' );
    is( $info->{max_packet_size}, 1518, 'Max packet size ok' );
    is( $info->{min_packet_size}, 1518, 'Min packet size ok' );
    is( $info->{play_duration_ms}, 2602, 'Play duration ok' );
    is( $info->{preroll}, 1579, 'Preroll ok' );
    is( $info->{seekable}, 1, 'Seekable ok' );
    is( $info->{send_duration_ms}, 1857, 'Send duration ok' );
    is( $info->{song_length_ms}, 1023, 'Song length ok' );
    is( $info->{dlna_profile}, 'WMABASE', 'DLNA profile WMABASE ok' );
    
    is( ref $info->{streams}, 'ARRAY', 'Streams ok' );
    
    my $stream = $info->{streams}->[0];
    
    is( $stream->{DeviceConformanceTemplate}, 'L2', 'DeviceConformanceTemplate ok' );
    is( $stream->{IsVBR}, 0, 'IsVBR ok' );
    is( $stream->{alt_bitrate}, 32024, 'Alt bitrate ok' );
    is( $stream->{alt_buffer_fullness}, 0, 'Alt buffer fullness ok' );
    is( $stream->{alt_buffer_size}, 1579, 'Alt buffer size ok' );
    is( $stream->{avg_bitrate}, 32645, 'Average bitrate ok' );
    is( $stream->{avg_bytes_per_sec}, 4003, 'Average bytes/sec ok' );
    is( $stream->{bitrate}, 32024, 'Bitrate ok' );
    is( $stream->{bits_per_sample}, 16, 'Bits per sample ok' );
    is( $stream->{block_alignment}, 1487, 'Block alignment ok' );
    is( $stream->{buffer_fullness}, 0, 'Buffer fullness ok' );
    is( $stream->{buffer_size}, 1579, 'Buffer size ok' );
    is( $stream->{channels}, 2, 'Channels ok' );
    is( $stream->{codec_id}, 0x161, 'Codec ID ok' );
    is( $stream->{encode_options}, 23, 'Encode options ok' );
    is( $stream->{encrypted}, 0, 'Encrypted ok' );
    is( $stream->{error_correction_type}, 'ASF_Audio_Spread', 'Error correction type ok' );
    is( $stream->{flag_seekable}, 1, 'Seekable ok' );
    is( $stream->{language_index}, 0, 'Language index ok' );
    is( $stream->{max_object_size}, 1487, 'Max object size ok' );
    is( $stream->{samplerate}, 22050, 'Sample rate ok' );
    is( $stream->{samples_per_block}, 17408, 'Samples per block ok' );
    is( $stream->{stream_number}, 1, 'Stream number ok' );
    is( $stream->{stream_type}, 'ASF_Audio_Media', 'Stream type ok' );
    is( $stream->{super_block_align}, 0, 'Super block align ok' );
    is( $stream->{time_offset}, 0, 'Time offset ok' );
    
    is( $tags->{Author}, 'Author String', 'Author tag ok' );
    is( $tags->{Copyright}, 'Copyright String', 'Copyright tag ok' );
    is( $tags->{Description}, 'Description String', 'Description tag ok' );
    is( $tags->{IsVBR}, 0, 'IsVBR tags ok' );
    is( $tags->{Rating}, 'Rating String', 'Rating tag ok' );
    is( $tags->{Title}, 'Voice Test', 'Title tag ok' );
    is( $tags->{WMFSDKNeeded}, '0.0.0.0000', 'WMFSDKNeeded tag ok' );
    is( $tags->{WMFSDKVersion}, '11.0.5721.5251', 'WMFSDKVersion tag ok' );
}

# Multiple bitrate file
{
    my $s = Audio::Scan->scan( _f('wma92-mbr.wma') );
    
    my $info = $s->{info};
    my $tags = $s->{tags};
    
    is( ref $info->{mutex_list}, 'ARRAY', 'Mutex list ok' );
    is( $info->{mutex_list}->[0]->{ASF_Mutex_Bitrate}->[0], 1, 'Mutex stream 1 ok' );
    is( $info->{mutex_list}->[0]->{ASF_Mutex_Bitrate}->[1], 2, 'Mutex stream 2 ok' );
    
    is( $info->{streams}->[0]->{stream_number}, 1, 'Stream 1 ok' );
    is( $info->{streams}->[1]->{stream_number}, 2, 'Stream 2 ok' );
    
    is( $tags->{'User Key'}, 'User Value', 'User key ok' );
}

# VBR file
{
    my $s = Audio::Scan->scan( _f('wma92-vbr.wma') );
    
    my $info = $s->{info};
    my $tags = $s->{tags};
    
    is( $info->{streams}->[0]->{IsVBR}, 1, 'IsVBR ok' );
    is( $info->{streams}->[0]->{avg_bitrate}, 53719, 'Average bitrate ok' );
    
    SKIP:
    {
        skip 'Encode is not available', 3 unless $HAS_ENCODE;
        my $pate = Encode::decode_utf8("pâté");
        my $ber  = Encode::decode_utf8('ЪЭЯ');
        my $yc   = Encode::decode_utf8('γζ');
    
        is( $tags->{'Latin1 Key'}, $pate, 'Latin1 tag ok' );
        is( $tags->{'Russian Key'}, $ber, 'Unicode tag ok' );
        is( $tags->{$ber}, $yc, 'Unicode key/value ok' );
    }
    
    is( ref $tags->{'WM/Picture'}, 'HASH', 'WM/Picture ok' );
    is( $tags->{'WM/Picture'}->{image_type}, 3, 'WM/Picture type ok' );
    is( $tags->{'WM/Picture'}->{mime_type}, 'image/jpeg', 'WM/Picture MIME type ok' );
    is( length($tags->{'WM/Picture'}->{image}), 2103, 'WM/Picture length ok' );
}

# Test ignoring artwork
{
    local $ENV{AUDIO_SCAN_NO_ARTWORK} = 1;
    
    my $s = Audio::Scan->scan( _f('wma92-vbr.wma') );
    
    my $tags = $s->{tags};
    
    is( $tags->{'WM/Picture'}->{image}, 2103, 'WM/Picture with AUDIO_SCAN_NO_ARTWORK ok' );
    is( $tags->{'WM/Picture'}->{offset}, 555, 'WM/Picture with AUDIO_SCAN_NO_ARTWORK offset ok' );
}

# Bug 17355, WM/Picture tag within Header Extension/Metadata Library
{
    local $ENV{AUDIO_SCAN_NO_ARTWORK} = 1;
    
    my $s = Audio::Scan->scan( _f('bug17355-picture-offset.wma') );
    
    my $tags = $s->{tags};
    
    is( $tags->{'WM/Picture'}->{image}, 88902, 'WM/Picture in Header Extension/Metadata Library length ok' );
    is( $tags->{'WM/Picture'}->{offset}, 1121, 'WM/Picture in Header Extension/Metadata Library length ok' );
}

# WMA Pro 10 file
{
    my $s = Audio::Scan->scan( _f('wma92-48k-pro.wma') );
    
    my $info = $s->{info};
    
    is( $info->{codec_list}->[0]->{name}, 'Windows Media Audio 10 Professional', 'WMA 10 Pro ok' );
    is( $info->{streams}->[0]->{codec_id}, 0x0162, 'WMA 10 Pro codec ID ok' );
    is( $info->{dlna_profile}, 'WMAPRO', 'WMA 10 Pro DLNA profile WMAPRO ok' );
}

# WMA Lossless file
{
    my $s = Audio::Scan->scan( _f('wma92-lossless.wma') );
    
    my $info = $s->{info};
    
    is( $info->{codec_list}->[0]->{name}, 'Windows Media Audio 9.2 Lossless', 'WMA Lossless ok' );
    is( $info->{streams}->[0]->{codec_id}, 0x0163, 'WMA Lossless codec ID ok' );
    is( $info->{streams}->[0]->{avg_bitrate}, 607494, 'WMA Lossless average bitrate ok' );
    is( $info->{lossless}, 1, 'WMA Lossless flag ok' );
    is( $info->{dlna_profile}, 'WMALSL', 'WMA Lossless DLNA profile WMALSL ok' );
}

# WMA Voice file with duplicate tags
{
    my $s = Audio::Scan->scan( _f('wma92-voice.wma') );
    
    my $info = $s->{info};
    my $tags = $s->{tags};
    
    is( $info->{streams}->[0]->{codec_id}, 0x000a, 'WMA Voice codec ID ok' );
    ok( !exists $info->{dlna_profile}, 'WMA Voice no DLNA profile ok' );
    
    # Note these are out of order because they are written to different objects by MP3tag
    is( ref $tags->{'WM/Composer'}, 'ARRAY', 'Multiple composer tags ok' );
    is( $tags->{'WM/Composer'}->[0], 'Composer 2', 'Composer 2 ok' );
    is( $tags->{'WM/Composer'}->[1], 'Composer 3', 'Composer 3 ok' );
    is( $tags->{'WM/Composer'}->[2], 'Composer 1', 'Composer 1 ok' );
}

# WMV file, no audio
{
    my $s = Audio::Scan->scan( _f('wmv92.wmv') );
    
    my $info = $s->{info};
    
    my $stream = $info->{streams}->[0];
    
    is( $info->{codec_list}->[0]->{name}, 'Windows Media Video 9 Screen', 'WMV ok' );
    is( $stream->{stream_type}, 'ASF_Video_Media', 'WMV stream type ok' );
    is( $stream->{bpp}, 24, 'WMV bpp ok' );
    is( $stream->{compression_id}, 'MSS2', 'WMV compression ID ok' );
    is( $stream->{height}, 57, 'WMV height ok' );
    is( $stream->{width}, 501, 'WMV width ok' );
}

# Video/Audio file
{
	my $s = Audio::Scan->scan( _f('wmv92-with-audio.wmv') );
    
    my $info = $s->{info};
    
    is( $info->{codec_list}->[0]->{name}, 'Windows Media Audio 9.2', 'WMV audio track ok' );
    is( $info->{codec_list}->[1]->{name}, 'Windows Media Video 9', 'WMV video track ok' );
    is( $info->{dlna_profile}, 'WMAFULL', 'WMV with audio DLNA profile WMAFULL ok' );
    
    is( $info->{streams}->[0]->{stream_type}, 'ASF_Audio_Media', 'WMV audio stream ok' );
    is( $info->{streams}->[1]->{stream_type}, 'ASF_Video_Media', 'WMV video stream ok' );
}

# Live audio stream header
{
    my $s = Audio::Scan->scan( _f('wma-live.wma') );
    
    my $info = $s->{info};
    
    is( $info->{broadcast}, 1, 'Live stream ok' );
    is( $info->{seekable}, 0, 'Live stream not seekable ok' );
    
    is( $info->{streams}->[1]->{stream_type}, 'ASF_Command_Media', 'Live stream metadata stream ok' );
}

# File with DRM, script commands, and 2 images
{
    my $s = Audio::Scan->scan( _f('drm.wma') );
    
    my $info = $s->{info};
    my $tags = $s->{tags};
    
    is( $info->{streams}->[0]->{encrypted}, 1, 'DRM encrypted flag set ok' );
    is( $info->{drm_key}, 'pMYQ3zAwEE+/lAEL5hP0Ug==', 'DRM key ok' );
    is( $info->{drm_license_url}, 'http://switchboard.real.com/rhapsody/?cd=wmupgrade', 'DRM license URL ok' );
    is( $info->{drm_protection_type}, 'DRM', 'DRM protection type ok' );
    
    like( $info->{drm_data}, qr{<RhapsodyAlbumArtistId>16826</RhapsodyAlbumArtistId>}, 'Extended encryption data ok' );

    is( ref $info->{script_types}, 'ARRAY', 'Script types ok' );
    is( $info->{script_types}->[0], 'URL', 'Script type URL ok' );
    is( $info->{script_types}->[1], 'FILENAME', 'Script type FILENAME ok' );
    is( ref $info->{script_commands}, 'ARRAY', 'Script commands ok' );
    is( $info->{script_commands}->[0]->{command}, 'http://www.microsoft.com/isapi/redir.dll?Prd=WMT4&Sbp=DRM&Plcid=0x0409&Pver=4.0&WMTFeature=DRM', 'Script command 1 ok' );
    is( $info->{script_commands}->[0]->{time}, 1579, 'Script time 1 ok' );
    is( $info->{script_commands}->[0]->{type}, 0, 'Script type 1 ok' );
    is( $info->{script_commands}->[1]->{command}, undef, 'Script command 2 ok' );
    is( $info->{script_commands}->[1]->{time}, 1579, 'Script time 2 ok' );
    is( $info->{script_commands}->[1]->{type}, 1, 'Script type 2 ok' );
    
    is( ref $tags->{'WM/Picture'}, 'ARRAY', 'WM/Picture array ok' );
    is( $tags->{'WM/Picture'}->[0]->{description}, 'Large Cover Art', 'WM/Picture 1 description ok' );
    is( length( $tags->{'WM/Picture'}->[0]->{image} ), 4644, 'WM/Picture 1 image ok' );
    is( $tags->{'WM/Picture'}->[1]->{description}, 'Cover Art', 'WM/Picture 2 description ok' );
    is( length( $tags->{'WM/Picture'}->[1]->{image} ), 2110, 'WM/Picture 2 image ok ');
}

# File with JFIF image type and MP3 codec
{
    my $s = Audio::Scan->scan( _f('jfif.wma') );
    
    my $info = $s->{info};
    
    is( $info->{streams}->[0]->{stream_type}, 'ASF_JFIF_Media', 'JFIF stream ok' );
    is( $info->{streams}->[1]->{codec_id}, 85, 'MP3 codec ID ok' );
    is( $info->{streams}->[0]->{width}, 320, 'JFIF width ok' );
    is( $info->{streams}->[0]->{height}, 240, 'JFIF height ok' );
    ok( !exists $info->{dlna_profile}, 'MP3 codec no DLNA profile ok' );
}

# Bug 14788, multiple tags where one is an integer, caused a crash
{
    my $s = Audio::Scan->scan( _f('wma92-multiple-tags.wma') );
    
    my $tags = $s->{tags};
    
    is( $tags->{'WM/TrackNumber'}->[0], 1, 'Multiple tag Track Number ok' );
    is( $tags->{'WM/TrackNumber'}->[1], '01', 'Multiple tag Track Number ok' );
}

# Scan via a filehandle
{
    open my $fh, '<', _f('wma92-32k.wma');
    
    my $s = Audio::Scan->scan_fh( asf => $fh );
    
    my $info = $s->{info};
    my $tags = $s->{tags};
    
    is( $info->{audio_offset}, 5161, 'Audio offset ok via filehandle' );
    is( $tags->{Author}, 'Author String', 'Author tag ok via filehandle' );
    
    close $fh;
}

# Find frame MBR
{
    my $offset = Audio::Scan->find_frame( _f('wma92-mbr.wma'), 650 );
    
    is( $offset, 6261, 'Find frame MBR ok' );
    
    # Offset bigger than song_length_ms
    $offset = Audio::Scan->find_frame( _f('wma92-mbr.wma'), 1300 );
    
    is( $offset, 7061, 'Find frame MBR with retry ok' );
}

{
    open my $fh, '<', _f('wma92-mbr.wma');
    my $offset = Audio::Scan->find_frame_fh( asf => $fh, 1025 );
    close $fh;
    
    is( $offset, 7061, 'Find frame MBR via filehandle ok' );
}

# Find frame VBR
{
    my $offset = Audio::Scan->find_frame( _f('wma92-vbr.wma'), 2200 );
    is( $offset, 9825, 'Find frame VBR time 2200 ok' );
    
    $offset = Audio::Scan->find_frame( _f('wma92-vbr.wma'), 800 );
    is( $offset, 7564, 'Find frame VBR time 800 ok' );
    
    $offset = Audio::Scan->find_frame( _f('wma92-vbr.wma'), 0 );
    is( $offset, 5303, 'Find frame VBR time 0 ok' );    
}

{
    open my $fh, '<', _f('wma92-vbr.wma');
    my $offset = Audio::Scan->find_frame_fh( asf => $fh, 1000 );
    close $fh;
    
    is( $offset, 9825, 'Find frame VBR via filehandle ok' );
}

# Find frame CBR with no ASF_Index object
{
    my $offset = Audio::Scan->find_frame( _f('wma92-32k.wma'), 740 );
    is( $offset, 6679, 'Find frame CBR without ASF_Index ok' );
}

sub _f {
    return catfile( $FindBin::Bin, 'asf', shift );
}