File Coverage

blib/lib/StreamFinder/BannedVideo.pm
Criterion Covered Total %
statement 18 237 7.5
branch 0 162 0.0
condition 0 36 0.0
subroutine 6 17 35.2
pod 11 11 100.0
total 35 463 7.5


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             StreamFinder::Banned.Video - Fetch actual raw streamable video URLs from banned.video.
4              
5             =head1 AUTHOR
6              
7             This module is Copyright (C) 2019 by
8              
9             Jim Turner, C<< >>
10            
11             Email: turnerjw784@yahoo.com
12              
13             All rights reserved.
14              
15             You may distribute this module under the terms of either the GNU General
16             Public License or the Artistic License, as specified in the Perl README
17             file.
18              
19             =head1 SYNOPSIS
20              
21             use strict;
22              
23             use StreamFinder::BannedVideo;
24              
25             my $video = new StreamFinder::BannedVideo();
26              
27             die "Invalid URL or no streams found!\n" unless ($video);
28              
29             my $firstStream = $video->get();
30              
31             print "First Stream URL=$firstStream\n";
32              
33             my $url = $video->getURL();
34              
35             print "Stream URL=$url\n";
36              
37             my $videoTitle = $video->getTitle();
38            
39             print "Title=$videoTitle\n";
40            
41             my $videoDescription = $video->getTitle('desc');
42            
43             print "Description=$videoDescription\n";
44            
45             my $videoID = $video->getID();
46              
47             print "Video ID=$videoID\n";
48            
49             my $icon_url = $video->getIconURL();
50              
51             if ($icon_url) { #SAVE THE ICON TO A TEMP. FILE:
52              
53             my ($image_ext, $icon_image) = $video->getIconData();
54              
55             if ($icon_image && open IMGOUT, ">/tmp/${videoID}.$image_ext") {
56              
57             binmode IMGOUT;
58              
59             print IMGOUT $icon_image;
60              
61             close IMGOUT;
62              
63             }
64              
65             }
66              
67             my $stream_count = $video->count();
68              
69             print "--Stream count=$stream_count=\n";
70              
71             my @streams = $video->get();
72              
73             foreach my $s (@streams) {
74              
75             print "------ stream URL=$s=\n";
76              
77             }
78              
79             =head1 DESCRIPTION
80              
81             StreamFinder::BannedVideo accepts a valid video ID or URL on Banned.Video
82             (Alex Jones's infowars' new video site after "communist" YouTube BANNED his
83             videos) and, at the moment, youtube-dl doesn't convert them (yet?);
84             and returns the actual title, stream URL(s) and cover art icon for that video.
85             The purpose is that one needs one of these URLs in order to have the option to
86             stream the video in one's own choice of media player software rather than
87             using their web browser and accepting any / all flash, ads, javascript,
88             cookies, trackers, web-bugs, censorship, and other crapware that can come with
89             that method of playing. The author uses his own custom all-purpose media
90             player called "fauxdacious" (his custom hacked version of the open-source
91             "audacious" audio player). "fauxdacious" can incorporate this module to decode
92             and play banned.video streams.
93              
94             One or more stream URLs can be returned for each video.
95              
96             =head1 SUBROUTINES/METHODS
97              
98             =over 4
99              
100             =item B(I [, I<-keep> => "type1,type2?..." | [type1,type2?...] ] | [, I<-debug> [ => 0|1|2 ] ])
101              
102             Accepts a Banned.Video video ID or URL and creates and returns a new video object,
103             or I if the URL is not a valid Banned.Video video or no streams are found.
104             The URL can be the full URL,
105             ie. https://banned.video/watch?id=B, or just I.
106              
107             The optional I argument can be either a comma-separated string or an array
108             reference ([...]) of stream types to keep (include) and returned in order
109             specified (type1, type2...). Each "type" can be one of: extension (ie.
110             m4a, mp4, etc.), "direct", "stream", or ("any" or "all").
111              
112             DEFAULT keep list is: 'm4a,direct,stream', meaning that all m4a streams followed
113             by all "direct" streams ("directUrl" in page, followed by all remaining
114             (non-direct "streamUrl") streams. More than one value can be specified to
115             control order of search.
116              
117             =item $video->B()
118              
119             Returns an array of strings representing all stream URLs found.
120              
121             =item $video->B([I])
122              
123             Similar to B() except it only returns a single stream representing
124             the first valid stream found.
125              
126             Current options are: I<"random"> and I<"noplaylists">. By default, the
127             first ("best"?) stream is returned. If I<"random"> is specified, then
128             a random one is selected from the list of streams found.
129             If I<"noplaylists"> is specified, and the stream to be returned is a
130             "playlist" (.pls or .m3u? extension), it is first fetched and the first entry
131             in the playlist is returned. This is needed by Fauxdacious Mediaplayer.
132              
133             =item $video->B()
134              
135             Returns the number of streams found for the video.
136              
137             =item $video->B(['fccid'])
138              
139             Returns the video's Banned.Video ID, or FCC call-letters.
140              
141             =item $video->B(['desc'])
142              
143             Returns the video's title, or (long description).
144              
145             =item $video->B()
146              
147             Returns the URL for the video's "cover art" icon image, if any.
148              
149             =item $video->B()
150              
151             Returns a two-element array consisting of the extension (ie. "png",
152             "gif", "jpeg", etc.) and the actual icon image (binary data), if any.
153              
154             =item $video->B()
155              
156             Returns the URL for the video's "cover art" (usually larger)
157             banner image.
158              
159             =item $video->B()
160              
161             Returns a two-element array consisting of the extension (ie. "png",
162             "gif", "jpeg", etc.) and the actual video's banner image (binary data).
163              
164             =item $video->B()
165              
166             Returns the video's type ("BannedVideo").
167              
168             =back
169              
170             =head1 CONFIGURATION FILES
171              
172             =over 4
173              
174             =item ~/.config/StreamFinder/BannedVideo/config
175              
176             Optional text file for specifying various configuration options
177             for a specific site (submodule). Each option is specified on a
178             separate line in the format below:
179              
180             'option' => 'value' [,]
181              
182             and the options are loaded into a hash used only by the specific
183             (submodule) specified. Valid options include
184             I<-debug> => [0|1|2], and most of the L options.
185             Blank lines and lines starting with a "#" sign are ignored.
186              
187             Options specified here override any specified in I<~/.config/StreamFinder/config>.
188              
189             Among options valid for BannedVideo streams is the I<-keep> option
190             described in the B function.
191              
192             =item ~/.config/StreamFinder/config
193              
194             Optional text file for specifying various configuration options.
195             Each option is specified on a separate line in the format below:
196              
197             'option' => 'value' [,]
198              
199             and the options are loaded into a hash used by all sites
200             (submodules) that support them. Valid options include
201             I<-debug> => [0|1|2], and most of the L options.
202              
203             =back
204              
205             NOTE: Options specified in the options parameter list will override
206             those corresponding options specified in these files.
207              
208             =head1 KEYWORDS
209              
210             BannedVideo
211              
212             =head1 DEPENDENCIES
213              
214             L, L, L
215              
216             =head1 RECCOMENDS
217              
218             wget
219              
220             =head1 BUGS
221              
222             Please report any bugs or feature requests to C, or through
223             the web interface at L. I will be notified, and then you'll
224             automatically be notified of progress on your bug as I make changes.
225              
226             =head1 SUPPORT
227              
228             You can find documentation for this module with the perldoc command.
229              
230             perldoc StreamFinder::BannedVideo
231              
232             You can also look for information at:
233              
234             =over 4
235              
236             =item * RT: CPAN's request tracker (report bugs here)
237              
238             L
239              
240             =item * AnnoCPAN: Annotated CPAN documentation
241              
242             L
243              
244             =item * CPAN Ratings
245              
246             L
247              
248             =item * Search CPAN
249              
250             L
251              
252             =back
253              
254             =head1 LICENSE AND COPYRIGHT
255              
256             Copyright 2019 Jim Turner.
257              
258             This program is free software; you can redistribute it and/or modify it
259             under the terms of the the Artistic License (2.0). You may obtain a
260             copy of the full license at:
261              
262             L
263              
264             Any use, modification, and distribution of the Standard or Modified
265             Versions is governed by this Artistic License. By using, modifying or
266             distributing the Package, you accept this license. Do not use, modify,
267             or distribute the Package, if you do not accept this license.
268              
269             If your Modified Version has been derived from a Modified Version made
270             by someone other than you, you are nevertheless required to ensure that
271             your Modified Version complies with the requirements of this license.
272              
273             This license does not grant you the right to use any trademark, service
274             mark, tradename, or logo of the Copyright Holder.
275              
276             This license includes the non-exclusive, worldwide, free-of-charge
277             patent license to make, have made, use, offer to sell, sell, import and
278             otherwise transfer the Package with respect to any patent claims
279             licensable by the Copyright Holder that are necessarily infringed by the
280             Package. If you institute patent litigation (including a cross-claim or
281             counterclaim) against any party alleging that the Package constitutes
282             direct or contributory patent infringement, then this Artistic License
283             to you shall terminate on the date that such litigation is filed.
284              
285             Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER
286             AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
287             THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
288             PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY
289             YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR
290             CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR
291             CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE,
292             EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
293              
294             =cut
295              
296             package StreamFinder::BannedVideo;
297              
298 1     1   7 use strict;
  1         1  
  1         53  
299 1     1   6 use warnings;
  1         2  
  1         24  
300 1     1   76 use URI::Escape;
  1         3  
  1         49  
301 1     1   5 use HTML::Entities ();
  1         1  
  1         23  
302 1     1   5 use LWP::UserAgent ();
  1         2  
  1         16  
303 1     1   4 use vars qw(@ISA @EXPORT);
  1         2  
  1         2896  
304              
305             my $DEBUG = 0;
306             my %uops = ();
307             my @userAgentOps = ();
308              
309             require Exporter;
310              
311             @ISA = qw(Exporter);
312             @EXPORT = qw(get getURL getType getID getTitle getIconURL getIconData getImageURL getImageData);
313              
314             sub new
315             {
316 0     0 1   my $class = shift;
317 0           my $url = shift;
318              
319 0           my $self = {};
320 0 0         return undef unless ($url);
321              
322 0           my @okStreams;
323              
324 0           foreach my $p ("$ENV{HOME}/.config/StreamFinder/config", "$ENV{HOME}/.config/StreamFinder/Youtube/config") {
325 0 0         if (open IN, $p) {
326 0           my ($atr, $val);
327 0           while () {
328 0           chomp;
329 0 0         next if (/^\s*\#/o);
330 0           ($atr, $val) = split(/\s*\=\>\s*/o, $_, 2);
331 0           eval "\$uops{$atr} = $val";
332             }
333 0           close IN;
334             }
335             }
336 0           foreach my $i (qw(agent from conn_cache default_headers local_address ssl_opts max_size
337             max_redirect parse_head protocols_allowed protocols_forbidden requests_redirectable
338             proxy no_proxy)) {
339 0 0         push @userAgentOps, $i, $uops{$i} if (defined $uops{$i});
340             }
341             push (@userAgentOps, 'agent', 'Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0')
342 0 0         unless (defined $uops{'agent'});
343 0 0         $uops{'timeout'} = 10 unless (defined $uops{'timeout'});
344 0 0         $DEBUG = $uops{'debug'} if (defined $uops{'debug'});
345              
346 0           while (@_) {
347 0 0         if ($_[0] =~ /^\-?debug$/o) {
    0          
348 0           shift;
349 0 0 0       $DEBUG = (defined($_[0]) && $_[0] =~/^[0-9]$/) ? shift : 1;
350             } elsif ($_[0] =~ /^\-?keep$/o) {
351 0           shift;
352 0 0         if (defined $_[0]) {
353 0           my $keeporder = shift;
354 0 0         @okStreams = (ref($keeporder) =~ /ARRAY/) ? @{$keeporder} : split(/\,\s*/, $keeporder);
  0            
355             }
356             } else {
357 0           shift;
358             }
359             }
360 0 0 0       if (!defined($okStreams[0]) && defined($uops{'keep'})) {
361 0 0         @okStreams = (ref($uops{'keep'}) =~ /ARRAY/) ? @{$uops{'keep'}} : split(/\,\s*/, $uops{'keep'});
  0            
362             }
363 0 0         @okStreams = (qw(m4a direct stream any)) unless (defined $okStreams[0]); # one of: {m4a, , direct, stream, any, all}
364              
365 0 0         print STDERR "-0(BannedVideo): URL=$url=\n" if ($DEBUG);
366              
367 0           (my $url2fetch = $url);
368 0 0         if ($url =~ /^https?\:/) {
369 0 0         $self->{'id'} = $1 if ($url2fetch =~ m#\/([^\/]+)\/?$#);
370 0           $self->{'id'} =~ s#^(?:watch\?)?id\=##;
371             } else {
372 0           $self->{'id'} = $url;
373 0           $url2fetch = 'https://banned.video/watch?id=' . $url;
374             }
375 0 0         return undef unless ($self->{'id'});
376              
377 0           $self->{'cnt'} = 0;
378 0           my $html = '';
379 0 0         print STDERR "-0(BannedVideo): ID=".$self->{'id'}."= URL=$url2fetch=\n" if ($DEBUG);
380 0           my $ua = LWP::UserAgent->new(@userAgentOps);
381 0           $ua->timeout($uops{'timeout'});
382 0           $ua->cookie_jar({});
383 0           $ua->env_proxy;
384 0           my $response = $ua->get($url2fetch);
385 0 0         if ($response->is_success) {
386 0           $html = $response->decoded_content;
387             } else {
388 0 0         print STDERR $response->status_line if ($DEBUG);
389 0           my $no_wget = system('wget','-V');
390 0 0         unless ($no_wget) {
391 0 0         print STDERR "\n..trying wget...\n" if ($DEBUG);
392 0           $html = `wget -t 2 -T 20 -O- -o /dev/null \"$url2fetch\" 2>/dev/null `;
393             }
394             }
395 0 0         print STDERR "-1: html=$html=\n" if ($DEBUG > 1);
396 0 0         return undef unless ($html); #STEP 1 FAILED, INVALID VIDEO URL, PUNT!
397              
398 0           my $stindex = 0;
399 0           my @streams = ();
400 0           foreach my $streamtype (@okStreams) {
401 0           while ($html =~ s/\"(?:embed|direct|stream)Url\"\s*\:\s*\"([^\"]+?\.${streamtype}\b[^\"]*)\"//is) {
402 0           $streams[$stindex++] = $1;
403             }
404 0 0         if ($streamtype =~ /^(embed|direct|stream)$/i) {
    0          
405 0           my $one = $1;
406 0           while ($html =~ s/\"${one}Url\"\s*\:\s*\"([^\"]+)\"//is) {
407 0           $streams[$stindex++] = $1;
408             }
409             } elsif ($streamtype =~ /^a(?:ny|ll)$/i) {
410 0           while ($html =~ s/\"(?:embed|direct|stream)Url\"\s*\:\s*\"([^\"]+)\"//is) {
411 0           $streams[$stindex++] = $1;
412             }
413             }
414             }
415 0 0         print STDERR "-2: 1=$streams[0]= 2=$streams[1]\n" if ($DEBUG);
416 0 0         return undef unless ($#streams >= 0);
417              
418             #HACK B/C THEY COMPLICATED UP THEIR SITE (FETCH STREAM FROM FIRST infowarsmedia.com URL FOUND
419             #AND ADD IT TO THE TOP)! :/
420 0           for (my $i=0;$i<=$#streams;$i++) {
421 0 0         if ($streams[$i] =~ m#api\.infowarsmedia\.com/embed#o) {
422 0           my $html = '';
423 0 0         print STDERR "---STEP 2: INFOWARSMEDIA.COM STREAM ($streams[$i])\n" if ($DEBUG);
424 0           $url2fetch = $streams[$i];
425 0           my $response = $ua->get($url2fetch);
426 0 0         if ($response->is_success) {
427 0           $html = $response->decoded_content;
428             } else {
429 0 0         print STDERR $response->status_line if ($DEBUG);
430 0           my $no_wget = system('wget','-V');
431 0 0         unless ($no_wget) {
432 0 0         print STDERR "\n..trying wget...\n" if ($DEBUG);
433 0           $html = `wget -t 2 -T 20 -O- -o /dev/null \"$url2fetch\" 2>/dev/null `;
434             }
435             }
436 0 0         print STDERR "-STEP 2: html=$html=\n" if ($DEBUG > 1);
437 0 0         if ($html =~ m#\bdownloadUrl\=\"([^\"]+)\"#) {
438 0 0         print STDERR "-3: WILL USE ($1) AS BEST STREAM.\n" if ($DEBUG);
439 0           unshift @streams, $1;
440 0           last;
441             }
442             }
443             }
444              
445 0           $self->{'cnt'} = scalar @streams;
446 0           $html =~ s/\\\"/\"\;/gs;
447 0 0         $self->{'title'} = ($html =~ /\"title\"\s*\:\s*\"([^\"]+)\"/is) ? $1 : '';
448 0 0         $self->{'description'} = ($html =~ m#\bname\=\"description\"\s+content\=\"([^\"]+)\"#s) ? $1 : $self->{'title'};
449 0           $self->{'title'} = HTML::Entities::decode_entities($self->{'title'});
450 0           $self->{'title'} = uri_unescape($self->{'title'});
451 0           $self->{'description'} = HTML::Entities::decode_entities($self->{'description'});
452 0           $self->{'description'} = uri_unescape($self->{'description'});
453 0 0         $self->{'iconurl'} = ($html =~ /\"(?:poster)?ThumbnailUrl\"\s*\:\s*\"([^\"]+)\"/is) ? $1 : '';
454 0 0         $self->{'imageurl'} = ($html =~ /\"posterLargeUrl\"\s*\:\s*\"([^\"]+)\"/is) ? $1 : '';
455 0 0         $self->{'imageurl'} = $1 if ($html =~ /\"largeImage\"\s*\:\s*\"([^\"]+)\"/is) ? $1 : '';
    0          
456 0   0       $self->{'iconurl'} ||= $self->{'imageurl'};
457 0   0       $self->{'imageurl'} ||= $self->{'iconurl'};
458 0 0         $self->{'created'} = $1 if ($html =~ /\"createdAt\"\s*\:\s*\"([^\"]+)\"/is);
459 0 0         $self->{'updated'} = $1 if ($html =~ /\"updatedAt\"\s*\:\s*\"([^\"]+)\"/is);
460 0 0 0       if (defined $self->{'updated'} && $self->{'updated'} =~ /(\d\d\d\d)/) {
461 0           $self->{'year'} = $1;
462             } else {
463 0 0 0       $self->{'year'} = $1 if (defined($self->{'created'}) && $self->{'created'} =~ /(\d\d\d\d)/);
464             }
465              
466 0           $self->{'streams'} = \@streams; #WE'LL HAVE A LIST OF 'EM TO RANDOMLY CHOOSE ONE FROM:
467 0           $self->{'total'} = $self->{'cnt'};
468 0 0         print STDERR "-(all)count=".$self->{'cnt'}."= iconurl=".$self->{'iconurl'}."=\n" if ($DEBUG);
469 0 0         print STDERR "-SUCCESS: 1st stream=".${$self->{'streams'}}[0]."=\ntitle=".$self->{'title'}."=\n" if ($DEBUG);
  0            
470              
471 0           bless $self, $class; #BLESS IT!
472              
473 0           return $self;
474             }
475              
476             sub get
477             {
478 0     0 1   my $self = shift;
479              
480 0 0         return wantarray ? @{$self->{'streams'}} : ${$self->{'streams'}}[0];
  0            
  0            
481             }
482              
483             sub getURL #LIKE GET, BUT ONLY RETURN THE SINGLE ONE W/BEST BANDWIDTH AND RELIABILITY:
484             {
485 0     0 1   my $self = shift;
486 0 0         my $arglist = (defined $_[0]) ? join('|',@_) : '';
487 0 0         my $idx = ($arglist =~ /\b\-?random\b/) ? int rand scalar @{$self->{'streams'}} : 0;
  0            
488 0 0 0       if ($arglist =~ /\b\-?noplaylists\b/ && ${$self->{'streams'}}[$idx] =~ /\.(pls|m3u8?)$/i) {
  0            
489 0           my $plType = $1;
490 0           my $firstStream = ${$self->{'streams'}}[$idx];
  0            
491 0 0         print STDERR "-getURL($idx): NOPLAYLISTS and (".${$self->{'streams'}}[$idx].")\n" if ($DEBUG);
  0            
492 0           my $ua = LWP::UserAgent->new(@userAgentOps);
493 0           $ua->timeout($uops{'timeout'});
494 0           $ua->cookie_jar({});
495 0           $ua->env_proxy;
496 0           my $html = '';
497 0           my $response = $ua->get($firstStream);
498 0 0         if ($response->is_success) {
499 0           $html = $response->decoded_content;
500             } else {
501 0 0         print STDERR $response->status_line if ($DEBUG);
502 0           my $no_wget = system('wget','-V');
503 0 0         unless ($no_wget) {
504 0 0         print STDERR "\n..trying wget...\n" if ($DEBUG);
505 0           $html = `wget -t 2 -T 20 -O- -o /dev/null \"$firstStream\" 2>/dev/null `;
506             }
507             }
508 0           my @lines = split(/\r?\n/, $html);
509 0           $firstStream = '';
510 0 0         if ($plType =~ /pls/) { #PLS:
511 0           my $firstTitle = '';
512 0           foreach my $line (@lines) {
513 0 0         if ($line =~ m#^\s*File\d+\=(.+)$#) {
    0          
514 0   0       $firstStream ||= $1;
515             } elsif ($line =~ m#^\s*Title\d+\=(.+)$#) {
516 0   0       $firstTitle ||= $1;
517             }
518             }
519 0   0       $self->{'title'} ||= $firstTitle;
520 0 0         print STDERR "-getURL(PLS): first=$firstStream= title=$firstTitle=\n" if ($DEBUG);
521             } else { #m3u8:
522 0           (my $urlpath = ${$self->{'streams'}}[$idx]) =~ s#[^\/]+$##;
  0            
523 0           foreach my $line (@lines) {
524 0 0         if ($line =~ m#^\s*([^\#].+)$#) {
525 0           my $urlpart = $1;
526 0           $urlpart =~ s#^\s+##;
527 0           $urlpart =~ s#^\/##;
528 0 0         $firstStream = ($urlpart =~ m#https?\:#) ? $urlpart : ($urlpath . '/' . $urlpart);
529 0           last;
530             }
531             }
532 0 0         print STDERR "-getURL(m3u?): first=$firstStream=\n" if ($DEBUG);
533             }
534 0   0       return $firstStream || ${$self->{'streams'}}[$idx];
535             }
536 0           return ${$self->{'streams'}}[$idx];
  0            
537             }
538              
539             sub count
540             {
541 0     0 1   my $self = shift;
542 0           return $self->{'total'}; #TOTAL NUMBER OF PLAYABLE STREAM URLS FOUND.
543             }
544              
545             sub getType
546             {
547 0     0 1   my $self = shift;
548 0           return 'BannedVideo'; #STATION TYPE (FOR PARENT StreamFinder MODULE).
549             }
550              
551             sub getID
552             {
553 0     0 1   my $self = shift;
554 0           return $self->{'id'};
555             }
556              
557             sub getTitle
558             {
559 0     0 1   my $self = shift;
560 0 0 0       return $self->{'description'} if (defined($_[0]) && $_[0] =~ /^\-?(?:long|desc)/i);
561 0           return $self->{'title'}; #VIDEO'S TITLE(DESCRIPTION), IF ANY.
562             }
563              
564             sub getIconURL
565             {
566 0     0 1   my $self = shift;
567 0           return $self->{'iconurl'}; #URL TO THE VIDEO'S THUMBNAIL ICON, IF ANY.
568             }
569              
570             sub getIconData
571             {
572 0     0 1   my $self = shift;
573 0 0         return () unless ($self->{'iconurl'});
574              
575 0           my $ua = LWP::UserAgent->new(@userAgentOps);
576 0           $ua->timeout($uops{'timeout'});
577 0           $ua->cookie_jar({});
578 0           $ua->env_proxy;
579 0           my $art_image = '';
580 0           my $response = $ua->get($self->{'iconurl'});
581 0 0         if ($response->is_success) {
582 0           $art_image = $response->decoded_content;
583             } else {
584 0 0         print STDERR $response->status_line if ($DEBUG);
585 0           my $no_wget = system('wget','-V');
586 0 0         unless ($no_wget) {
587 0 0         print STDERR "\n..trying wget...\n" if ($DEBUG);
588 0           my $iconUrl = $self->{'iconurl'};
589 0           $art_image = `wget -t 2 -T 20 -O- -o /dev/null \"$iconUrl\" 2>/dev/null `;
590             }
591             }
592 0 0         return () unless ($art_image);
593              
594 0           (my $image_ext = $self->{'iconurl'}) =~ s/^.+\.//;
595 0           $image_ext =~ s/[^A-Za-z].*$//;
596              
597 0           return ($image_ext, $art_image);
598             }
599              
600             sub getImageURL
601             {
602 0     0 1   my $self = shift;
603 0           return $self->{'imageurl'}; #URL TO THE VIDEO'S BANNER IMAGE, IF ANY.
604             }
605              
606             sub getImageData
607             {
608 0     0 1   my $self = shift;
609 0 0         return () unless ($self->{'imageurl'});
610 0           my $ua = LWP::UserAgent->new(@userAgentOps);
611 0           $ua->timeout($uops{'timeout'});
612 0           $ua->cookie_jar({});
613 0           $ua->env_proxy;
614 0           my $art_image = '';
615 0           my $response = $ua->get($self->{'imageurl'});
616 0 0         if ($response->is_success) {
617 0           $art_image = $response->decoded_content;
618             } else {
619 0 0         print STDERR $response->status_line if ($DEBUG);
620 0           my $no_wget = system('wget','-V');
621 0 0         unless ($no_wget) {
622 0 0         print STDERR "\n..trying wget...\n" if ($DEBUG);
623 0           my $iconUrl = $self->{'iconurl'};
624 0           $art_image = `wget -t 2 -T 20 -O- -o /dev/null \"$iconUrl\" 2>/dev/null `;
625             }
626             }
627 0 0         return () unless ($art_image);
628 0           my $image_ext = $self->{'imageurl'};
629 0 0         $image_ext = ($self->{'imageurl'} =~ /\.(\w+)$/) ? $1 : 'png';
630 0           $image_ext =~ s/[^A-Za-z].*$//;
631 0           return ($image_ext, $art_image);
632             }
633              
634             1