view release on metacpan or search on metacpan
lib/StreamFinder/Anystream.pm view on Meta::CPAN
my $response = $ua->get($url2fetch);
if ($response->is_success) {
$html = $response->decoded_content;
} else {
print STDERR $response->status_line if ($DEBUG);
}
unless ($html) { #STEP 1 FAILED, INVALID URL, PUNT!
print STDERR "-!!!- COULD NOT FETCH URL=$url2fetch=\n" if ($DEBUG);
return undef;
}
my $isHLSpage = ($html =~ /#EXTM3U/) ? 1 : 0; #SEE AUDACIOUS ISSUE#1169 FOR EMBEDDED HLS IN HTML PAGE EXAMPLE USED FOR THIS CODE:
my $streamExts = join('|',@okStreams);
print STDERR "-1: HLS=$isHLSpage=\n----html=$html=\n" if ($DEBUG > 1);
return undef unless ($html =~ /\<\!DOCTYPE\s+(?:html|text)/i
|| ($isHLSpage && $streamExts =~ /(?:m3u8|any|all)/i)); #STEP 1 FAILED, INVALID STATION URL, PUNT!
print STDERR "-1: GOT SOME(<=2048 BYTES) HTML!\n" if ($DEBUG);
$ua->requests_redirectable([]) if ($isHLSpage);
unless ($isHLSpage) {
print STDERR "-1a: NOW RE-FETCH FULL PAGE!\n" if ($DEBUG);
$ua->max_size(undef); #(NOW OK TO FETCH THE WHOLE DOCUMENT)
lib/StreamFinder/Apple.pm view on Meta::CPAN
my $no_wget = system('wget','-V');
unless ($no_wget) {
print STDERR "\n..trying wget...\n" if ($DEBUG);
$html = `wget -t 2 -T 20 -O- -o /dev/null "$url2fetch" 2>/dev/null `;
}
}
print STDERR "-1: html=$html=\n" if ($DEBUG > 1);
return undef unless ($html);
if ($url2fetch =~ s#\/\/embed.podcast#\/\/podcast#) { #HANDLE "EMBEDDED PODCAST URLS:
print STDERR "--2a: EMBEDDED PODCAST, take 5, then fetch podcast page ($url2fetch)...\n" if ($DEBUG);
sleep 5; #AVOID HITTING 'EM TOO QUICK IN SUCCESSION (AVOID DOS SUSPICION):
$response = $ua->get($url2fetch);
if ($response->is_success) { #JETCH PODCAST PAGE:
$html = $response->decoded_content;
} else {
print STDERR $response->status_line if ($DEBUG);
my $no_wget = system('wget','-V');
unless ($no_wget) {
print STDERR "\n..trying wget...\n" if ($DEBUG);
$html = `wget -t 2 -T 20 -O- -o /dev/null "$url2fetch" 2>/dev/null `;
}
}
print STDERR "-1: html=$html=\n" if ($DEBUG > 1);
return undef unless ($html);
if ($html =~ m#${url2fetch}\?i\=(\d+)#s) {
$self->{'id'} = $1;
$url2fetch .= '?i=' . $1;
print STDERR "--3: EMBEDDED EPISODE FOUND (id=$1): URL=$url2fetch)!\n" if ($DEBUG);
} else {
print STDERR "f:Could not find embedded episode in ($url2fetch), aborting!\n";
return undef;
}
} else {
$url2fetch = ($html =~ m#\,\"uploadDate\"\:\"[^\"]+\"\,\"url\"\:\"([^\"]+)#)
? $1 : '';
return undef unless ($url2fetch);
$self->{'id'} = ($url2fetch =~ m#\/(?:id)?(\d\d\d\d\d+)(?:\?i\=(\d+))?\/?#) ? $1 : '';
$self->{'id'} .= '/'. $2 if (defined $2);
lib/StreamFinder/BrandNewTube.pm view on Meta::CPAN
$self->{'albumartist'} ||= $1;
($self->{'artist'} = $2) =~ s#\s+$##s;
}
#TRY TO FETCH STREAMS:
while ($html =~ s#\<source\s+.*?src\=\"([^\"]+)\"##s) {
my $one = $1;
push @{$self->{'streams'}}, $one unless ($self->{'secure'} && $one !~ /^https/);
$self->{'cnt'}++;
}
#STEP 2: TRY FETCHING THE EMBED URL UNLESS WE FOUND STREAM(S):
#DEPRECIATED? $url2fetch = $1 if ($self->{'cnt'} <= 0
#DEPRECIATED? && $html =~ m#\<iframe\s+src\=\"($baseURL\/embed\/[^\"]+)#s);
print STDERR "*** EMBED PAGE URL($1) FOUND!\n" if ($self->{'cnt'} <= 0
&& $html =~ m#\<iframe\s+src\=\"($baseURL\/embed\/[^\"]+)#s);
}
}
$self->{'cnt'} = scalar @{$self->{'streams'}};
$self->{'title'} =~ s/\s+\-\s+$self->{'artist'}\s*$//; #CONVERT "Title - Artist" => "Title"
foreach my $field (qw(description artist title)) {
$self->{$field} = HTML::Entities::decode_entities($self->{$field});
$self->{$field} = uri_unescape($self->{$field});
$self->{$field} =~ s/(?:\%|\\?u?00)([0-9A-Fa-f]{2})/chr(hex($1))/eg;
lib/StreamFinder/PodcastAddict.pm view on Meta::CPAN
my @epiStreams = ();
my $ua = LWP::UserAgent->new(@{$self->{'_userAgentOps'}});
$ua->timeout($self->{'timeout'});
$ua->cookie_jar({});
$ua->env_proxy;
my $html = '';
my $response;
my $isEpisode;
#NOTE: THE ONLY "EPISODE" URLS NOW USED BY PODCASTADDICT ARE THE URI-ESCAPED ONES CONTAINING
#THE STREAM URL EMBEDDED IN THEIR PODCAST PAGES (WITH NO EPISODE-ID#) AND HAVE THE FORMAT (EXAMPLE):
#"https://podcastaddict.com/episode/https%3A%2F%2Fpscrb.fm%2Frss%2Fp%2Fpdst.fm%2Fe%2Farttrk.com%2Fp%2FABMA5%2Faudioboom.com%2Fposts%2F8280770.mp3%3Fmodified%3D1681401989%26sid%3D2399216%26source%3Drss&podcastId=1719501"
#TO PREVENT USING THE FULL STREAM-URL FOR THE UNIQUE EPISODE-ID#, WE JUST USE THE PODCAST-ID#.
#NO KNOWN WAY EXISTS FOR FETCHING EPISODES VIA JUST A PODCAST AND EPISODE-ID, THEREFORE WE CAN'T
#DETERMINE WHAT THE REAL EPISODE-ID IS, EXCEPT ON PODCAST PAGES STILL USING THE CLASSIC, UNESCAPED
#EPISODE-URLS (format: "https://podcastaddict.com/episode/<episode-ID-number>")!
#(NOTE ALSO THAT THE "&podcastId=#####" PART OF THE URL IS *NOT* THE SEARCHABLE PODCAST-ID EITHER,
#BUT RATHER THE PODCAST ARTIST'S/CHANNEL ID#)!
TRYIT:
if ($url2fetch =~ m#^([0-9]+)$#) { #ASSUME PODCAST-ID, AS EPISODES NO LONGER HAVE DESCERNABLE IDs:
$self->{'id'} = $1;
$url2fetch = "$baseURL/podcast/".$self->{'id'};
$isEpisode = 0;
print STDERR "-1- PODCAST ID, ID=".$self->{'id'}."= found ($url2fetch)\n" if ($DEBUG);
} elsif ($url2fetch =~ m#\/episode\/https?#) { #(LONG) EPISODE URL (ON PODCAST PAGES, ESCAPED):
$url2fetch = uri_escape($url2fetch) unless($url2fetch =~ m#\%3A#); #PODCASTADDICT EPISODE URLS NOW MUST BE URI-ESCAPED!
#$self->{'id'} IS NOT EMBEDDED OR DETERMINABLE, WILL SET TO PODCAST-ID LATER!
$isEpisode = 1;
print STDERR "-2- EPISODE URL, ID=UNKNOWN= found ($url2fetch)\n" if ($DEBUG);
} elsif ($url2fetch =~ m#\/episode\/(\d+)\/?$#) { #CLASSIC (SHORT) EPISODE URL WITH ID. (DEPRECIATED)
$self->{'id'} = $2; #CLASSIC EPISODE URLS HAVE A PROPER EPISODE-ID EMBEDDED!
$isEpisode = 1;
print STDERR "-3- CLASSIC EPISODE URL, ID=".$self->{'id'}."= found ($url2fetch)\n" if ($DEBUG);
} elsif ($url2fetch =~ m#\/podcast\/([^\/]+)#) { #PODCAST URL
$self->{'id'} = $1; #USE UNIQUE NUMBER AS A MADE-UP "EPISODE-ID"
$self->{'id'} = $1 if ($url2fetch =~ m#\/(\d\d\d\d+)$#);
$isEpisode = 0;
print STDERR "-4- PODCAST URL, ID=".$self->{'id'}."= found ($url2fetch)\n" if ($DEBUG);
} elsif ($url2fetch =~ m#^([^\/]+)\/(\d+)#) { #EPISODE-ID:
my $podcastID = $1;
my $episodeID = $2;
lib/StreamFinder/Rumble.pm view on Meta::CPAN
#STEP 2: FETCH THE STREAMS FROM THE "embedUrl":
return $url2;
}
return '';
};
local *getEmbedPage = sub {
my $url2fetch = shift;
my $html = '';
print STDERR "-FETCHING EMBED URL=$url2fetch=\n" if ($DEBUG);
$response = $ua->get($url2fetch);
if ($response->is_success) {
$html = $response->decoded_content;
} else {
print STDERR $response->status_line if ($DEBUG);
my $no_wget = system('wget','-V');
unless ($no_wget) {
print STDERR "\n..trying wget...\n" if ($DEBUG);
$html = `wget -t 2 -T 20 -O- -o /dev/null "$url2fetch" 2>/dev/null `;
}
lib/StreamFinder/Rumble.pm view on Meta::CPAN
}
if ($html =~ m#\"author\"\:\{\"name\"\:\"([^\"]+)\"\,\"url\"\:\"([^\"]+)#s) {
$self->{'artist'} ||= $1;
$self->{'albumartist'} ||= $2;
}
if ($html =~ m#\"pubDate\"\:\"([^\"]+)#s) {
$self->{'created'} = $1;
$self->{'year'} ||= $1 if ($self->{'created'} =~ /(\d\d\d\d)/);
}
if ($html =~ m#\"i\"\:\"([^\"]+)#s) { #GRAB EMBEDDED IMAGE URL IN CASE MAIN PAGE IS "PRIVATE"(UNFETCHABLE):
$self->{'iconurl'} ||= $1;
$self->{'imageurl'} ||= $self->{'iconurl'};
}
return $url2;
} else {
$url2fetch =~ s#\/embed\/#\/#;
print STDERR "---EMBED PAGE: NO HTML, TRY CHANNEL PAGE ($url2fetch)!...\n" if ($DEBUG);
return &getChannelPage($url2fetch);
}
return '';
};
$url = "$baseURL/embed/${url}/" if ($url !~ m#http# && $url !~ m#\-#);
my $tried = 0;
TRYIT:
print STDERR "-${tried}(Rumble): URL=$url=\n" if ($DEBUG);
if ($url =~ m#\/embed\/#i) {
lib/StreamFinder/Spreaker.pm view on Meta::CPAN
$self->{'year'} = $1 if ($self->{'created'} =~ /(\d\d\d\d)/o);
my $stream = ($html =~ m#\"download\_url\"\:\"([^\"]+)#s) ? $1 : '';
if ($stream) {
unless ($self->{'secure'} && $stream !~ /^https/o) {
push @epiTitles, $self->{'title'};
push @epiStreams, $stream;
push @{$self->{'streams'}}, $stream;
$self->{'cnt'}++;
}
}
} else { #EXTRACT PODCAST PAGE DATA FROM EMBEDDED, ENCODED JSON:
$html = HTML::Entities::decode_entities($html);
$html = uri_unescape($html);
$html =~ s#\\\/#\/#gs;
$self->{'album'} = ($html =~ m#\<meta\s+property\=\"(?:og|twitter)\:title\"\s+content\=\"([^\"]+)\"\s*\/\>#s) ? $1 : '';
$self->{'articonurl'} = ($html =~ m#\<link\s+rel\=\"image\_src\"\s+href\=\"([^\"]+)#s) ? $1 : '';
$self->{'articonurl'} ||= ($html =~ m#\<meta\s+property\=\"(?:og|twitter)\:image\"\s+content\=\"([^\"]+)\"\s*\/\>#s) ? $1 : '';
$self->{'artist'} = ($html =~ m#\"fullname\"\:\"([^\"]+)#s) ? $1 : '';
$self->{'genre'} = ($html =~ m#\"category\_id\"\:\d+\,\"name\"\:\"([^\"]+)#s) ? $1 : '';
my $episodes = $1 if ($html =~ m#\"episodes\"\:\[(.+)$#s);
lib/StreamFinder/Youtube.pm view on Meta::CPAN
} elsif ($_[0] =~ /^\-?youtube-dl-args$/o) {
shift;
$self->{'youtube-dl-args'} = shift if (defined $_[0]);
} elsif ($_[0] =~ /^\-?youtube-dl-add-args$/o) {
shift;
$self->{'youtube-dl-add-args'} = shift if (defined $_[0]);
} else {
shift; #DISCARD ANY OTHERS.
}
}
$self->{'youtubeonly'} = 1 if ($self->{'noiframes'}); #NO EMBEDDED RUMBLE-SEARCH IF NO IFRAMES ALLOWED!
$self->{'youtube-dl'} = 'yt-dlp' unless (defined $self->{'youtube-dl'});
print STDERR "-0(Youtube): URL=$url=\n" if ($DEBUG);
$url =~ s/[\?\&]autoplay\=true$//; #STRIP THIS OFF SO WE DON'T HAVE TO.
$url =~ s/[\?\&]list\=.*$//; #yt-dlp SEEMS TO JUST HANG ON "lists" (TRYING TO FETCH A LIST OF VIDEOS?!).
(my $url2fetch = $url);
$self->{'_isaYtPage'} = 1;
#DEPRECIATED (STATION-IDS NOW INCLUDE STUFF BEFORE THE DASH: ($self->{'id'} = $url) =~ s#^.*\-([a-z]\d+)\/?$#$1#;
if ($url2fetch =~ m#^https?\:#) {
lib/StreamFinder/Youtube.pm view on Meta::CPAN
$self->{'id'} =~ s/^watch\?v\=//;
$self->{'id'} =~ s/[\?\&].*$//;
print STDERR "---FOUND 1ST EPISODE! FETCHING=$url2fetch= ID=".$self->{'id'}."=\n" if ($DEBUG);
goto DO_YTDL; #SKIP NON-YOUTUBE PAGE CHECK (NEXT PARAGRAPH):
}
}
print STDERR "u:DID NOT FIND A VIDEO ON CHANNEL/USER PAGE, PUNT!" if ($DEBUG);
return undef;
}
#IF NON-YOUTUBE PAGE, LOOK FOR ANYTHING EMBEDDED IN AN IFRAME:
unless ($self->{'_isaYtPage'} || $self->{'noiframes'}) {
print STDERR "..1a:See if we have a StreamFinder-supported URL in 1st iframe?...\n" if ($DEBUG);
my $embedded_video;
my $html = '';
my $ua = LWP::UserAgent->new(@{$self->{'_userAgentOps'}});
$ua->timeout($self->{'timeout'});
$ua->max_size(1024); #LIMIT FETCH-SIZE TO AVOID INFINITELY DOWNLOADING A STREAM!
$ua->cookie_jar({});
$ua->env_proxy;
lib/StreamFinder/Youtube.pm view on Meta::CPAN
print STDERR "--embedded YOUTUBE JSON url=$url2fetch=\n" if ($DEBUG);
$self->{'_isaYtPage'} = 1;
$self->{'id'} = $1 if ($url2fetch =~ m#\/([^\/]+)\/?$#);
$self->{'id'} =~ s/^watch\?v\=//;
$self->{'id'} =~ s/[\?\&].*$//;
$self->{'id'} = $1 if (!$self->{'_isaYtPage'} && $url2fetch =~ m#id[\=\:\#]?([^\/\s\=\:\#]+)#);
last;
}
unless ($self->{'youtubeonly'}) {
if ($html =~ /\bRumble\s*\(\"play\"\,\s+\{\"video\"\:\"([a-z0-9\-\_]+)\"/si) {
#EXTRACT CERTAIN EMBEDDED RUMBLE VIDEOS NOT NECESSARILY IN AN IFRAME:
my $embeddedURL = 'https://rumble.com/embed/' . $1;
my $haveRumble = 0;
print STDERR "---FOUND AN EMBEDDED RUMBLE VIDEO ($embeddedURL), SEE IF WE CAN GO WITH THAT!\n" if ($DEBUG);
eval { require 'StreamFinder/Rumble.pm'; $haveRumble = 1; };
if ($haveRumble) {
my %globalArgs = (-debug => $DEBUG);
foreach my $arg (qw(log logfmt)) {
$globalArgs{$arg} = $self->{$arg} if (defined($self->{$arg}) && $self->{$arg});
}
$embedded_video = new StreamFinder::Rumble($embeddedURL, %globalArgs);
return $embedded_video if (defined($embedded_video) && $embedded_video->count() > 0);
}
}
lib/StreamFinder/Youtube.pm view on Meta::CPAN
}
}
#NOW MANUALLY SCRAPE YOUTUBE PAGE TO TRY TO GET artist, description, year, ETC. DIRECTLY FROM PAGE (IF A YOUTUBE SITE):
unless ($self->{'fast'}) { #(FAST MEANS SKIP SCRAPING YOUTUBE PAGE FOR ADDTL. METADATA)
$try = 0;
RETRYPAGE:
print STDERR "----(try2=$try= FETCHURL=$url2fetch= isYT?=".$self->{'_isaYtPage'}."=\n" if ($DEBUG);
if ($self->{'_isaYtPage'}) { #WE'RE A YOUTUBE PAGE, FETCH METADATA:
#CONVERT "embedded" YT PAGES TO ACTUAL PAGE (EMBEDDED PAGES DON'T HAVE THE METADATA WE'RE SEEKING!:
if ($url2fetch =~ m#^(.+?)\/embed\/([a-z0-9\-\_]{11})#i) { #TRY FETCHING YOUTUBE SITE FROM THE EMBEDDED URL:
$url2fetch = $1.'/watch?v='.$2;
} elsif ($url2fetch =~ m#^\/embed\/([a-z0-9\-\_]{11})#i) { #IF FAIL, TRY www.youtube.com:
$url2fetch = $self->{'youtube-site'} . '/watch?v=' .$1;
}
print STDERR "-2 (TRY=$try) FETCHING SCREEN URL=$url2fetch= ID=".$self->{'id'}."=\n" if ($DEBUG);
my $ua = LWP::UserAgent->new(@{$self->{'_userAgentOps'}});
$ua->timeout($self->{'timeout'});
$ua->cookie_jar({});
$ua->env_proxy;
my $html = '';