forked from squeezebox-googlemusic/squeezebox-googlemusic
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathProtocolHandler.pm
166 lines (126 loc) · 4.72 KB
/
ProtocolHandler.pm
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
package Plugins::GoogleMusic::ProtocolHandler;
use strict;
use warnings;
# On LMS 7.9.0 and greater, https support is handled by the new
# Slim::Player::Protocols::HTTPS library, which isn't available
# on older versions
use if (Slim::Utils::Versions->compareVersions($::VERSION, '7.9.0')) >= 0, base => qw(Slim::Player::Protocols::HTTPS);
use if (Slim::Utils::Versions->compareVersions($::VERSION, '7.9.0')) < 0, base => qw(Slim::Player::Protocols::HTTP);
use Scalar::Util qw(blessed);
use Slim::Player::Playlist;
use Slim::Utils::Log;
use Slim::Utils::Misc;
use Slim::Utils::Prefs;
use Plugins::GoogleMusic::Plugin;
use Plugins::GoogleMusic::GoogleAPI;
use Plugins::GoogleMusic::Image;
use Plugins::GoogleMusic::Library;
use Plugins::GoogleMusic::Recent;
my $log = logger('plugin.googlemusic');
my $prefs = preferences('plugin.googlemusic');
my $googleapi = Plugins::GoogleMusic::GoogleAPI::get();
Slim::Player::ProtocolHandlers->registerHandler('googlemusic', __PACKAGE__);
# To support remote streaming (synced players), we need to subclass Protocols::HTTP
sub new {
my $class = shift;
my $args = shift;
my $client = $args->{client};
my $song = $args->{song};
my $streamUrl = $song->streamUrl() || return;
my $track = $song->pluginData('info') || {};
main::DEBUGLOG && $log->debug( 'Remote streaming Google Music track: ' . $streamUrl );
my $sock = $class->SUPER::new( {
url => $streamUrl,
song => $song,
client => $client,
} ) || return;
${*$sock}{contentType} = 'audio/mpeg';
return $sock;
}
# Always MP3
sub getFormatForURL {
return 'mp3';
}
# Source for AudioScrobbler
sub audioScrobblerSource {
# P = Chosen by the user
return 'P';
}
sub scanStream {
my ($class, $url, $track, $args) = @_;
my $cb = $args->{cb} || sub {};
my $googleTrack = Plugins::GoogleMusic::Library::get_track($url);
# Add track to recent albums and artists
Plugins::GoogleMusic::Recent::recentAlbumsAdd($googleTrack->{album});
Plugins::GoogleMusic::Recent::recentArtistsAdd($googleTrack->{artist});
# To support seeking set duration and bitrate
$track->secs($googleTrack->{'secs'});
# Always 320k at Google Music
$track->bitrate(320000);
$track->content_type('mp3');
$track->artistname($googleTrack->{'artist'}->{'name'});
$track->albumname($googleTrack->{'album'}->{'name'});
$track->coverurl($googleTrack->{'cover'});
$track->title($googleTrack->{'title'});
$track->tracknum($googleTrack->{'trackNumber'});
$track->filesize($googleTrack->{'filesize'});
$track->year($googleTrack->{'year'});
$track->cover($googleTrack->{'cover'});
$track->stash->{'rating'} = $googleTrack->{'rating'};
$cb->( $track );
return;
}
sub getNextTrack {
my ($class, $song, $successCb, $errorCb) = @_;
my $client = $song->master();
my $url = $song->currentTrack()->url;
my ($id) = $url =~ m{^googlemusic:track:(.*)$}x;
my $trackURL;
eval {
$trackURL = $googleapi->get_stream_url($id, $prefs->get('device_id'));
};
if ($@) {
# We didn't get the next track to play
$log->error("Looking up stream url for url $url failed: $@");
my $error = ( $client->isPlaying(1) && $client->playingSong()->track()->url =~ /^googlemusic:track:/ )
? 'PLUGIN_GOOGLEMUSIC_NO_NEXT_TRACK'
: 'PLUGIN_GOOGLEMUSIC_NO_TRACK';
$errorCb->($error, $url);
# Set the title after the errro callback so the current title
# is still the title name during the callback
Slim::Music::Info::setCurrentTitle( $url, $client->string('PLUGIN_GOOGLEMUSIC_NO_TRACK') );
return;
}
eval {
$googleapi->increment_song_playcount($id);
};
if ($@) {
$log->error("Incrementing the play count for url $url failed: $@");
}
$song->streamUrl($trackURL);
$successCb->();
return;
}
sub canDirectStreamSong {
my ( $class, $client, $song ) = @_;
# We need to check with the base class (HTTP) to see if we
# are synced or if the user has set mp3StreamingMethod
return $class->SUPER::canDirectStream( $client, $song->streamUrl(), $class->getFormatForURL($song->track->url()) );
}
sub getMetadataFor {
my ($class, $client, $url) = @_;
my $track = Plugins::GoogleMusic::Library::get_track($url);
return {
title => $track->{'title'},
artist => $track->{'artist'}->{'name'},
album => $track->{'album'}->{'name'},
duration => $track->{'secs'},
cover => $track->{'cover'},
icon => $track->{'cover'},
bitrate => '320k CBR',
type => 'MP3 (Google Music)',
rating => $track->{'rating'},
};
}
1;
__END__