Skip to content

Commit

Permalink
提前获取播放链接,部分优化歌曲切换延迟 #317
Browse files Browse the repository at this point in the history
  • Loading branch information
gmg137 committed Dec 2, 2024
1 parent 27d3d04 commit 75b5375
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 3 deletions.
31 changes: 31 additions & 0 deletions src/application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ pub enum Action {
AddPlayList(Vec<SongInfo>, bool),
PlayListStart,
PersistVolume(f64),
GetSongUrl(SongInfo),
SetSongUrl(SongInfo),

// login
CheckLogin(UserMenuChild, CookieJar),
Expand Down Expand Up @@ -766,6 +768,35 @@ impl NeteaseCloudMusicGtk4Application {
Action::PersistVolume(value) => {
window.persist_volume(value);
}
Action::GetSongUrl(song_info) => {
let sender = imp.sender.clone();
let music_rate = window.settings().uint("music-rate");
let path = crate::path::get_music_cache_path(song_info.id, music_rate);

if !path.exists() {
MAINCONTEXT.spawn_local_with_priority(Priority::DEFAULT_IDLE, async move {
if let Ok(song_url) = ncmapi.songs_url(&[song_info.id], music_rate).await {
debug!("获取歌曲播放链接: {:?}", song_url);
if let Some(song_url) = song_url.first() {
let song_info = SongInfo {
song_url: song_url.url.to_owned(),
..song_info
};
sender.send(Action::SetSongUrl(song_info)).await.unwrap();
}
}
});
} else {
let song_info = SongInfo {
song_url: format!("file://{}", path.to_str().unwrap().to_owned()),
..song_info
};
window.set_song_url(song_info);
}
}
Action::SetSongUrl(song_info) => {
window.set_song_url(song_info);
}
Action::ToAlbumPage(songlist) => {
let page = window.init_songlist_page(&songlist, true);
window.page_new(&page, &songlist.name);
Expand Down
41 changes: 40 additions & 1 deletion src/audio/playlist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,17 @@ impl PlayList {
self.position = 0;
}

pub fn set_song_url(&mut self, si: SongInfo) {
if let Some(si_old) = self.list.iter_mut().find(|s| s.id == si.id) {
si_old.song_url = si.song_url.clone();
}
if let LoopsState::Shuffle = self.loops {
if let Some(si_old) = self.shuffle.iter_mut().find(|s| s.id == si.id) {
si_old.song_url = si.song_url;
}
}
}

pub fn set_play_state(&mut self, state: bool) {
self.play_state = state;
}
Expand Down Expand Up @@ -173,6 +184,34 @@ impl PlayList {
}

// 查询下一曲
pub fn get_next_song(&mut self) -> Option<&SongInfo> {
match self.loops {
LoopsState::Shuffle => {
if let Some(song) = self.shuffle.get(self.position + 1) {
Some(song)
} else {
self.shuffle.first()
}
}
LoopsState::Playlist => {
if let Some(song) = self.list.get(self.position + 1) {
Some(song)
} else {
self.list.first()
}
}
LoopsState::Track => self.list.get(self.position),
LoopsState::None => {
if let Some(song) = self.list.get(self.position + 1) {
Some(song)
} else {
None
}
}
}
}

// 获取下一曲
pub fn next_song(&mut self) -> Option<&SongInfo> {
match self.loops {
LoopsState::Shuffle => {
Expand Down Expand Up @@ -205,7 +244,7 @@ impl PlayList {
}
}

// 查询上一曲
// 获取上一曲
pub fn prev_song(&mut self) -> Option<&SongInfo> {
let position = if self.position == 0 {
0
Expand Down
19 changes: 17 additions & 2 deletions src/gui/player_controls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -316,13 +316,22 @@ impl PlayerControls {
);
}

let sender = imp.sender.get().unwrap();
if let Some(si) = self.get_current_song() {
// 发送更新歌词
let sender = imp.sender.get().unwrap();
sender
.send_blocking(Action::UpdateLyrics(si, msec / 1000))
.unwrap();
}

// 当剩余5秒时提前获取下首歌曲的播放链接。
let duration: u64 = self.property("duration");
let secp = (msec / 10u64.pow(5)) % 10;
if duration - sec == 5 && secp >= 5 {
if let Some(si) = self.get_next_song() {
sender.send_blocking(Action::GetSongUrl(si)).unwrap();
}
}
}

pub fn scale_value_update(&self) {
Expand Down Expand Up @@ -522,9 +531,15 @@ impl PlayerControls {
}
}

pub fn set_song_url(&self, si: SongInfo) {
if let Ok(mut playlist) = self.imp().playlist.lock() {
playlist.set_song_url(si);
}
}

pub fn get_next_song(&self) -> Option<SongInfo> {
if let Ok(mut playlist) = self.imp().playlist.lock() {
return playlist.next_song().map(|s| s.to_owned());
return playlist.get_next_song().map(|s| s.to_owned());
}
None
}
Expand Down
3 changes: 3 additions & 0 deletions src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,9 @@ impl NeteaseCloudMusicGtk4Window {
}
}

pub fn set_song_url(&self, si: SongInfo) {
self.imp().player_controls.get().set_song_url(si);
}
pub fn gst_duration_changed(&self, sec: u64) {
self.imp().player_controls.get().gst_duration_changed(sec);
}
Expand Down

0 comments on commit 75b5375

Please sign in to comment.