Broadcasting realisation.
This commit is contained in:
parent
fd263d60fe
commit
bff79664bc
|
@ -40,7 +40,8 @@ static const VkConnection::Scopes kScopes =
|
|||
VkConnection::Offline |
|
||||
VkConnection::Audio |
|
||||
VkConnection::Friends |
|
||||
VkConnection::Groups;
|
||||
VkConnection::Groups |
|
||||
VkConnection::Status;
|
||||
|
||||
static const char* kSettingsGroup = "Vk.com/oauth";
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ VkMusicCache::VkMusicCache(Application* app, VkService* service)
|
|||
: QObject(service),
|
||||
app_(app),
|
||||
service_(service),
|
||||
current_cashing_index(0),
|
||||
current_song_index(0),
|
||||
is_downloading(false),
|
||||
is_aborted(false),
|
||||
task_id(0),
|
||||
|
@ -38,31 +38,27 @@ VkMusicCache::VkMusicCache(Application* app, VkService* service)
|
|||
}
|
||||
|
||||
QUrl VkMusicCache::Get(const QUrl& url) {
|
||||
QString cached_filename = CachedFilename(url);
|
||||
QUrl result;
|
||||
if (InCache(cached_filename)) {
|
||||
if (InCache(url)) {
|
||||
QString cached_filename = CachedFilename(url);
|
||||
qLog(Info) << "Use cashed file" << cached_filename;
|
||||
result = QUrl::fromLocalFile(cached_filename);
|
||||
} else {
|
||||
result = service_->GetSongPlayUrl(url, false);
|
||||
|
||||
if (service_->isCachingEnabled()) {
|
||||
AddToQueue(cached_filename, result);
|
||||
current_cashing_index = queue_.size();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void VkMusicCache::ForceCache(const QUrl& url) {
|
||||
AddToQueue(CachedFilename(url), service_->GetSongPlayUrl(url));
|
||||
void VkMusicCache::AddToCache(const QUrl& url, const QUrl&media_url, bool force) {
|
||||
AddToQueue(CachedFilename(url), media_url);
|
||||
if (!force) {
|
||||
current_song_index = queue_.size();
|
||||
}
|
||||
}
|
||||
|
||||
void VkMusicCache::BreakCurrentCaching() {
|
||||
if (current_cashing_index > 0) {
|
||||
if (current_song_index > 0) {
|
||||
// Current song in queue
|
||||
queue_.removeAt(current_cashing_index - 1);
|
||||
} else if (current_cashing_index == 0) {
|
||||
queue_.removeAt(current_song_index - 1);
|
||||
} else if (current_song_index == 0) {
|
||||
// Current song is downloading
|
||||
if (reply_) {
|
||||
reply_->abort();
|
||||
|
@ -93,7 +89,7 @@ void VkMusicCache::DownloadNext() {
|
|||
} else {
|
||||
current_download = queue_.first();
|
||||
queue_.pop_front();
|
||||
current_cashing_index--;
|
||||
current_song_index--;
|
||||
|
||||
// Check file path and file existance first
|
||||
if (QFile::exists(current_download.filename)) {
|
||||
|
@ -181,12 +177,8 @@ void VkMusicCache::Downloaded() {
|
|||
* Utils
|
||||
*/
|
||||
|
||||
bool VkMusicCache::InCache(const QString& filename) {
|
||||
return QFile::exists(filename);
|
||||
}
|
||||
|
||||
bool VkMusicCache::InCache(const QUrl& url) {
|
||||
return InCache(CachedFilename(url));
|
||||
return QFile::exists(CachedFilename(url));
|
||||
}
|
||||
|
||||
QString VkMusicCache::CachedFilename(const QUrl& url) {
|
||||
|
|
|
@ -36,12 +36,11 @@ public:
|
|||
// Return file path if file in cache otherwise
|
||||
// return internet url and add song to caching queue
|
||||
QUrl Get(const QUrl& url);
|
||||
void ForceCache(const QUrl& url);
|
||||
void AddToCache(const QUrl& url, const QUrl& media_url, bool force = false);
|
||||
void BreakCurrentCaching();
|
||||
bool InCache(const QUrl& url);
|
||||
|
||||
private slots:
|
||||
bool InCache(const QString& filename);
|
||||
void AddToQueue(const QString& filename, const QUrl& download_url);
|
||||
void DownloadNext();
|
||||
void DownloadProgress(qint64 bytesReceived, qint64 bytesTotal);
|
||||
|
@ -63,9 +62,10 @@ private:
|
|||
Application* app_;
|
||||
VkService* service_;
|
||||
QList<DownloadItem> queue_;
|
||||
// Contain index of current song in queue, need for removing if song was skipped.
|
||||
// Is zero if song downloading now, and less that zero if current song not caching or cached.
|
||||
int current_cashing_index;
|
||||
// Contain index of current song in queue, need for removing if song was
|
||||
// skipped. It's zero if song downloading now, and less that zero
|
||||
// if current song not caching or cached.
|
||||
int current_song_index;
|
||||
DownloadItem current_download;
|
||||
bool is_downloading;
|
||||
bool is_aborted;
|
||||
|
|
|
@ -312,7 +312,7 @@ void VkService::EnsureMenuCreated() {
|
|||
|
||||
add_song_to_cache_ = context_menu_->addAction(QIcon(":vk/download.png"),
|
||||
tr("Add song to cache"), this,
|
||||
SLOT(AddToCache()));
|
||||
SLOT(AddSelectedToCache()));
|
||||
|
||||
copy_share_url_ = context_menu_->addAction(
|
||||
QIcon(":vk/link.png"), tr("Copy share url to clipboard"), this,
|
||||
|
@ -367,7 +367,7 @@ void VkService::ShowContextMenu(const QPoint& global_pos) {
|
|||
current.data(InternetModel::Role_SongMetadata).value<Song>();
|
||||
is_in_mymusic = is_my_music_item ||
|
||||
ExtractIds(selected_song_.url()).owner_id == UserID();
|
||||
is_cached = cache()->InCache(selected_song_.url());
|
||||
is_cached = cache_->InCache(selected_song_.url());
|
||||
}
|
||||
|
||||
update_item_->setVisible(is_updatable);
|
||||
|
@ -443,7 +443,7 @@ QList<QAction*> VkService::playlistitem_actions(const Song& song) {
|
|||
copy_share_url_->setVisible(true);
|
||||
actions << copy_share_url_;
|
||||
|
||||
if (!cache()->InCache(selected_song_.url())) {
|
||||
if (!cache_->InCache(selected_song_.url())) {
|
||||
add_song_to_cache_->setVisible(true);
|
||||
actions << add_song_to_cache_;
|
||||
}
|
||||
|
@ -835,7 +835,7 @@ void VkService::AddToMyMusic() {
|
|||
}
|
||||
|
||||
void VkService::AddToMyMusicCurrent() {
|
||||
if (isLoveAddToMyMusic()) {
|
||||
if (isLoveAddToMyMusic() && current_song_.is_valid()) {
|
||||
selected_song_ = current_song_;
|
||||
AddToMyMusic();
|
||||
}
|
||||
|
@ -852,8 +852,10 @@ void VkService::RemoveFromMyMusic() {
|
|||
}
|
||||
}
|
||||
|
||||
void VkService::AddToCache() {
|
||||
url_handler_->ForceAddToCache(selected_song_.url());
|
||||
void VkService::AddSelectedToCache() {
|
||||
QUrl selected_song_media_url =
|
||||
GetAudioItemFromUrl(selected_song_.url()).url();
|
||||
cache_->AddToCache(selected_song_.url(), selected_song_media_url, true);
|
||||
}
|
||||
|
||||
void VkService::CopyShareUrl() {
|
||||
|
@ -999,12 +1001,12 @@ SongList VkService::FromAudioList(const Vreen::AudioItemList& list) {
|
|||
* Url handling
|
||||
*/
|
||||
|
||||
QUrl VkService::GetSongPlayUrl(const QUrl& url, bool is_playing) {
|
||||
Vreen::AudioItem VkService::GetAudioItemFromUrl(const QUrl& url) {
|
||||
QStringList tokens = url.path().split('/');
|
||||
|
||||
if (tokens.count() < 2) {
|
||||
qLog(Error) << "Wrong song url" << url;
|
||||
return QUrl();
|
||||
return Vreen::AudioItem();
|
||||
}
|
||||
|
||||
QString song_id = tokens[1];
|
||||
|
@ -1016,17 +1018,35 @@ QUrl VkService::GetSongPlayUrl(const QUrl& url, bool is_playing) {
|
|||
bool success = WaitForReply(song_request);
|
||||
|
||||
if (success && !song_request->result().isEmpty()) {
|
||||
Vreen::AudioItem song = song_request->result()[0];
|
||||
if (is_playing) {
|
||||
current_song_ = FromAudioItem(song);
|
||||
current_song_.set_url(url);
|
||||
}
|
||||
return song.url();
|
||||
return song_request->result()[0];
|
||||
}
|
||||
}
|
||||
|
||||
qLog(Info) << "Unresolved url by id" << song_id;
|
||||
return QUrl();
|
||||
return Vreen::AudioItem();
|
||||
}
|
||||
|
||||
UrlHandler::LoadResult VkService::GetSongResult(const QUrl&url) {
|
||||
// Try get from cache
|
||||
QUrl media_url = cache_->Get(url);
|
||||
if (media_url.isValid()) {
|
||||
SongStarting(url);
|
||||
return UrlHandler::LoadResult(url, UrlHandler::LoadResult::TrackAvailable,
|
||||
media_url);
|
||||
}
|
||||
|
||||
// Otherwise get fresh link
|
||||
auto audio_item = GetAudioItemFromUrl(url);
|
||||
media_url = audio_item.url();
|
||||
if (media_url.isValid()) {
|
||||
Song song = FromAudioItem(audio_item);
|
||||
SongStarting(song);
|
||||
cache_->AddToCache(url, media_url);
|
||||
return UrlHandler::LoadResult(url, UrlHandler::LoadResult::TrackAvailable,
|
||||
media_url, song.length_nanosec());
|
||||
}
|
||||
|
||||
return UrlHandler::LoadResult();
|
||||
}
|
||||
|
||||
UrlHandler::LoadResult VkService::GetGroupNextSongUrl(const QUrl& url) {
|
||||
|
@ -1054,7 +1074,7 @@ UrlHandler::LoadResult VkService::GetGroupNextSongUrl(const QUrl& url) {
|
|||
if (success && !song_request->result().isEmpty()) {
|
||||
Vreen::AudioItem song = song_request->result()[0];
|
||||
current_group_url_ = url;
|
||||
current_song_ = FromAudioItem(song);
|
||||
SongStarting(FromAudioItem(song));
|
||||
emit StreamMetadataFound(url, current_song_);
|
||||
return UrlHandler::LoadResult(url, UrlHandler::LoadResult::TrackAvailable,
|
||||
song.url(), current_song_.length_nanosec());
|
||||
|
@ -1065,8 +1085,50 @@ UrlHandler::LoadResult VkService::GetGroupNextSongUrl(const QUrl& url) {
|
|||
return UrlHandler::LoadResult();
|
||||
}
|
||||
|
||||
void VkService::SetCurrentSongFromUrl(const QUrl& url) {
|
||||
current_song_ = SongFromUrl(url);
|
||||
/***
|
||||
* Song playing
|
||||
*/
|
||||
|
||||
void VkService::SongStarting(const QUrl& url) {
|
||||
SongStarting(SongFromUrl(url));
|
||||
}
|
||||
|
||||
void VkService::SongStarting(const Song &song)
|
||||
{
|
||||
current_song_ = song;
|
||||
|
||||
if (isBroadcasting() && HasAccount()) {
|
||||
auto id = ExtractIds(song.url());
|
||||
auto reply = audio_provider_->setBroadcast(id.audio_id, id.owner_id, IdList());
|
||||
NewClosure(reply, SIGNAL(resultReady(QVariant)), this,
|
||||
SLOT(BroadcastChangeReceived(Vreen::IntReply*)), reply);
|
||||
connect(app_->player(), SIGNAL(Stopped()), this, SLOT(SongStoped()),
|
||||
Qt::UniqueConnection);
|
||||
qLog(Debug) << "Broadcasting" << song.artist() << "-" << song.title();
|
||||
}
|
||||
}
|
||||
|
||||
void VkService::SongSkiped() {
|
||||
current_song_.set_valid(false);
|
||||
cache_->BreakCurrentCaching();
|
||||
}
|
||||
|
||||
void VkService::SongStoped()
|
||||
{
|
||||
current_song_.set_valid(false);
|
||||
|
||||
if (isBroadcasting() && HasAccount()) {
|
||||
auto reply = audio_provider_->resetBroadcast(IdList());
|
||||
NewClosure(reply, SIGNAL(resultReady(QVariant)), this,
|
||||
SLOT(BroadcastChangeReceived(Vreen::IntReply*)), reply);
|
||||
disconnect(app_->player(), SIGNAL(Stopped()), this, SLOT(SongStoped()));
|
||||
qLog(Debug) << "End of broadcasting";
|
||||
}
|
||||
}
|
||||
|
||||
void VkService::BroadcastChangeReceived(Vreen::IntReply *reply)
|
||||
{
|
||||
qLog(Debug) << "Broadcast changed for " << reply->result();
|
||||
}
|
||||
|
||||
/***
|
||||
|
@ -1234,6 +1296,12 @@ void VkService::ReloadSettings() {
|
|||
cacheFilename_ = s.value("cache_filename", kDefCacheFilename).toString();
|
||||
love_is_add_to_mymusic_ = s.value("love_is_add_to_my_music", false).toBool();
|
||||
groups_in_global_search_ = s.value("groups_in_global_search", false).toBool();
|
||||
|
||||
if (!s.contains("enable_broadcast")) {
|
||||
// Need to update premissions
|
||||
Logout();
|
||||
}
|
||||
enable_broadcast_ = s.value("enable_broadcast", false).toBool();
|
||||
}
|
||||
|
||||
void VkService::ClearStandardItem(QStandardItem* item) {
|
||||
|
|
|
@ -136,6 +136,8 @@ public:
|
|||
enum Role { Role_MusicOwnerMetadata = InternetModel::RoleCount,
|
||||
Role_AlbumMetadata };
|
||||
|
||||
Application* app() const { return app_; }
|
||||
|
||||
/* InternetService interface */
|
||||
QStandardItem* CreateRootItem();
|
||||
void LazyPopulate(QStandardItem* parent);
|
||||
|
@ -155,9 +157,11 @@ public:
|
|||
bool WaitForReply(Vreen::Reply* reply);
|
||||
|
||||
/* Music */
|
||||
VkMusicCache* cache() const { return cache_; }
|
||||
void SetCurrentSongFromUrl(const QUrl& url); // Used if song taked from cache.
|
||||
QUrl GetSongPlayUrl(const QUrl& url, bool is_playing = true);
|
||||
void SongStarting(const Song& song);
|
||||
void SongStarting(const QUrl& url); // Used if song taked from cache.
|
||||
void SongSkiped();
|
||||
UrlHandler::LoadResult GetSongResult(const QUrl& url);
|
||||
Vreen::AudioItem GetAudioItemFromUrl(const QUrl& url);
|
||||
// Return random song result from group playlist.
|
||||
UrlHandler::LoadResult GetGroupNextSongUrl(const QUrl& url);
|
||||
|
||||
|
@ -169,6 +173,7 @@ public:
|
|||
int maxGlobalSearch() const { return maxGlobalSearch_; }
|
||||
bool isCachingEnabled() const { return cachingEnabled_; }
|
||||
bool isGroupsInGlobalSearch() const { return groups_in_global_search_; }
|
||||
bool isBroadcasting() const { return enable_broadcast_; }
|
||||
QString cacheDir() const { return cacheDir_; }
|
||||
QString cacheFilename() const { return cacheFilename_; }
|
||||
bool isLoveAddToMyMusic() const { return love_is_add_to_mymusic_; }
|
||||
|
@ -197,6 +202,7 @@ private slots:
|
|||
void Error(Vreen::Client::Error error);
|
||||
|
||||
/* Music */
|
||||
void SongStoped();
|
||||
void UpdateMyMusic();
|
||||
void UpdateBookmarkSongs(QStandardItem* item);
|
||||
void UpdateAlbumSongs(QStandardItem* item);
|
||||
|
@ -208,7 +214,7 @@ private slots:
|
|||
void AddToMyMusic();
|
||||
void AddToMyMusicCurrent();
|
||||
void RemoveFromMyMusic();
|
||||
void AddToCache();
|
||||
void AddSelectedToCache();
|
||||
void CopyShareUrl();
|
||||
void ShowSearchDialog();
|
||||
|
||||
|
@ -219,6 +225,7 @@ private slots:
|
|||
void GroupSearchReceived(const SearchID& id, Vreen::Reply* reply);
|
||||
void UserOrGroupReceived(const SearchID& id, Vreen::Reply* reply);
|
||||
void AlbumListReceived(Vreen::AudioAlbumItemListReply* reply);
|
||||
void BroadcastChangeReceived(Vreen::IntReply* reply);
|
||||
|
||||
void AppendLoadedSongs(QStandardItem* item, Vreen::AudioItemListReply* reply);
|
||||
void RecommendationsLoaded(Vreen::AudioItemListReply* reply);
|
||||
|
@ -288,6 +295,7 @@ private:
|
|||
bool cachingEnabled_;
|
||||
bool love_is_add_to_mymusic_;
|
||||
bool groups_in_global_search_;
|
||||
bool enable_broadcast_;
|
||||
QString cacheDir_;
|
||||
QString cacheFilename_;
|
||||
};
|
||||
|
|
|
@ -45,12 +45,13 @@ VkSettingsPage::~VkSettingsPage() {
|
|||
void VkSettingsPage::Load() {
|
||||
service_->ReloadSettings();
|
||||
|
||||
ui_->maxGlobalSearch->setValue(service_->maxGlobalSearch());
|
||||
ui_->max_global_search->setValue(service_->maxGlobalSearch());
|
||||
ui_->enable_caching->setChecked(service_->isCachingEnabled());
|
||||
ui_->cache_dir->setText(service_->cacheDir());
|
||||
ui_->cache_filename->setText(service_->cacheFilename());
|
||||
ui_->love_button_is_add_to_mymusic->setChecked(service_->isLoveAddToMyMusic());
|
||||
ui_->groups_in_global_search->setChecked(service_->isGroupsInGlobalSearch());
|
||||
ui_->enable_broadcast->setChecked(service_->isBroadcasting());
|
||||
|
||||
if (service_->HasAccount()) {
|
||||
LogoutWidgets();
|
||||
|
@ -63,12 +64,13 @@ void VkSettingsPage::Save() {
|
|||
QSettings s;
|
||||
s.beginGroup(VkService::kSettingGroup);
|
||||
|
||||
s.setValue("max_global_search", ui_->maxGlobalSearch->value());
|
||||
s.setValue("max_global_search", ui_->max_global_search->value());
|
||||
s.setValue("cache_enabled", ui_->enable_caching->isChecked());
|
||||
s.setValue("cache_dir", ui_->cache_dir->text());
|
||||
s.setValue("cache_filename", ui_->cache_filename->text());
|
||||
s.setValue("love_is_add_to_my_music", ui_->love_button_is_add_to_mymusic->isChecked());
|
||||
s.setValue("groups_in_global_search", ui_->groups_in_global_search->isChecked());
|
||||
s.setValue("enable_broadcast", ui_->enable_broadcast->isChecked());
|
||||
|
||||
service_->ReloadSettings();
|
||||
}
|
||||
|
|
|
@ -64,12 +64,12 @@
|
|||
<string>Max global search results</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>maxGlobalSearch</cstring>
|
||||
<cstring>max_global_search</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="maxGlobalSearch">
|
||||
<widget class="QSpinBox" name="max_global_search">
|
||||
<property name="minimum">
|
||||
<number>50</number>
|
||||
</property>
|
||||
|
@ -110,6 +110,13 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="enable_broadcast">
|
||||
<property name="text">
|
||||
<string>Show playing song on your page</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "core/application.h"
|
||||
#include "core/logging.h"
|
||||
#include "core/player.h"
|
||||
|
||||
#include "vkservice.h"
|
||||
#include "vkmusiccache.h"
|
||||
|
@ -40,23 +41,19 @@ UrlHandler::LoadResult VkUrlHandler::StartLoading(const QUrl& url) {
|
|||
QString action = url.host();
|
||||
|
||||
if (action == "song") {
|
||||
service_->SetCurrentSongFromUrl(url);
|
||||
result = LoadResult(url, LoadResult::TrackAvailable, service_->cache()->Get(url));
|
||||
result = service_->GetSongResult(url);
|
||||
} else if (action == "group") {
|
||||
result = service_->GetGroupNextSongUrl(url);
|
||||
} else {
|
||||
qLog(Error) << "Invalid vk.com url action:" << action;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void VkUrlHandler::TrackSkipped() {
|
||||
service_->cache()->BreakCurrentCaching();
|
||||
}
|
||||
|
||||
void VkUrlHandler::ForceAddToCache(const QUrl& url) {
|
||||
service_->cache()->ForceCache(url);
|
||||
service_->SongSkiped();
|
||||
}
|
||||
|
||||
UrlHandler::LoadResult VkUrlHandler::LoadNext(const QUrl& url) {
|
||||
|
|
|
@ -34,7 +34,6 @@ public:
|
|||
QIcon icon() const { return QIcon(":providers/vk.png"); }
|
||||
LoadResult StartLoading(const QUrl& url);
|
||||
void TrackSkipped();
|
||||
void ForceAddToCache(const QUrl& url);
|
||||
LoadResult LoadNext(const QUrl& url);
|
||||
|
||||
private:
|
||||
|
|
Loading…
Reference in New Issue