forked from findechris/lms_mixcloud
-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #13 from philippe44/move-to-LMS-8.x
- Loading branch information
Showing
11 changed files
with
316 additions
and
5,446 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
package Plugins::MixCloud::Buffered; | ||
|
||
use strict; | ||
use base qw(Slim::Player::Protocols::HTTPS); | ||
|
||
use File::Temp; | ||
|
||
use Slim::Utils::Errno; | ||
use Slim::Utils::Log; | ||
use Slim::Utils::Prefs; | ||
|
||
my $log = logger('plugin.mixcloud'); | ||
my $prefs = preferences('plugin.mixcloud'); | ||
|
||
sub new { | ||
my $class = shift; | ||
my $self = $class->SUPER::new(@_); | ||
|
||
# HTTP headers have now been acquired in a blocking way by the above, we can | ||
# now enable fast download of body to a file from which we'll read further data | ||
# but the switch of socket handler can only be done within _sysread otherwise | ||
# we will timeout when there is a pipeline with a callback | ||
if (Slim::Utils::Misc->can('getTempDir')) { | ||
${*$self}{'_fh'} = File::Temp->new( DIR => Slim::Utils::Misc::getTempDir ); | ||
} else { | ||
${*$self}{'_fh'} = File::Temp->new; | ||
} | ||
open ${*$self}{'_rfh'}, '<', ${*$self}{'_fh'}->filename; | ||
binmode(${*$self}{'_rfh'}); | ||
|
||
return $self; | ||
} | ||
|
||
sub close { | ||
my $self = shift; | ||
|
||
# clean buffer file and all handlers | ||
Slim::Networking::Select::removeRead($self); | ||
${*$self}{'_rfh'}->close; | ||
delete ${*$self}{'_fh'}; | ||
|
||
$self->SUPER::close(@_); | ||
} | ||
|
||
# we need that call structure to make sure that SUPER calls the | ||
# object's parent, not the package's parent | ||
# see http://modernperlbooks.com/mt/2009/09/when-super-isnt.html | ||
sub _sysread { | ||
my $self = $_[0]; | ||
my $rfh = ${*$self}{'_rfh'}; | ||
|
||
# we are not ready to read body yet, read socket directly | ||
return $self->SUPER::_sysread($_[1], $_[2], $_[3]) unless $rfh; | ||
|
||
# first, try to read from buffer file | ||
my $readLength = $rfh->read($_[1], $_[2], $_[3]); | ||
return $readLength if $readLength; | ||
|
||
# assume that close() will be called for cleanup | ||
return 0 if ${*$self}{_done}; | ||
|
||
# empty file but not done yet, try to read directly | ||
$readLength = $self->SUPER::_sysread($_[1], $_[2], $_[3]); | ||
|
||
# if we now have data pending, likely we have been removed from the reading loop | ||
# so we have to re-insert ourselves (no need to store fresh data in buffer) | ||
if ($readLength) { | ||
Slim::Networking::Select::addRead($self, \&saveStream); | ||
return $readLength; | ||
} | ||
|
||
# use EINTR because EWOULDBLOCK (although faster) may overwrite our addRead() | ||
$! = EINTR; | ||
return undef; | ||
} | ||
|
||
sub saveStream { | ||
my $self = shift; | ||
|
||
my $bytes = $self->SUPER::_sysread(my $data, 32768); | ||
return unless defined $bytes; | ||
|
||
if ($bytes) { | ||
syswrite(${*$self}{'_fh'}, $data); | ||
${*$self}{'_rfh'}->seek(0, 1); | ||
} else { | ||
Slim::Networking::Select::removeRead($self); | ||
${*$self}{_done} = 1; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.