diff --git a/feeluown/gui/components/song_tag.py b/feeluown/gui/components/song_tag.py index dc5f1db9ed..ade527b93b 100644 --- a/feeluown/gui/components/song_tag.py +++ b/feeluown/gui/components/song_tag.py @@ -1,13 +1,18 @@ +from typing import TYPE_CHECKING + from PyQt5.QtWidgets import QLabel, QMenu from feeluown.utils.aio import run_afn from feeluown.media import MediaType +if TYPE_CHECKING: + from feeluown.app.gui_app import GuiApp + class SongSourceTag(QLabel): default_text = '音乐来源' - def __init__(self, app, font_size=12, parent=None): + def __init__(self, app: 'GuiApp', font_size=12, parent=None): super().__init__(text=SongSourceTag.default_text, parent=parent) self._app = app @@ -15,8 +20,13 @@ def __init__(self, app, font_size=12, parent=None): font.setPixelSize(font_size) self.setFont(font) + self._source = self.default_text + self._bitrate = 0 + self._app.player.metadata_changed.connect( self.on_metadata_changed, aioqueue=True) + self._app.player.audio_bitrate_changed.connect( + self.on_audio_bitrate_changed, aioqueue=True) def contextMenuEvent(self, e): # pylint: disable=unnecessary-direct-lambda-call @@ -37,28 +47,43 @@ def contextMenuEvent(self, e): ) menu.exec(e.globalPos()) + def on_audio_bitrate_changed(self, bitrate): + if bitrate is not None: + old_bitrate = self._bitrate + new_bitrate = bitrate // 1000 + # mpv's audio bitrate calculated on the packet level, + # only update text when the bitrate changes a lot. + self._bitrate = new_bitrate + if new_bitrate - old_bitrate > 10: + self.update_text() + def on_metadata_changed(self, metadata): if not metadata: - self.setText(SongSourceTag.default_text) - return - - text = '未知来源' - - # Fill source name. - source = metadata.get('source', '') - if source: - source_name_map = {p.identifier: p.name - for p in self._app.library.list()} - text = source_name_map.get(source, text) + self._source = '' + self._bitrate = 0 + else: + self._source = '未知来源' + # Fill source name. + source = metadata.get('source', '') + if source: + source_name_map = {p.identifier: p.name + for p in self._app.library.list()} + self._source = source_name_map.get(source, self._source) - # Fill audio bitrate info if available. - media = self._app.player.current_media - if media is not None and media.type_ == MediaType.audio: - props = media.props - if props.bitrate: - text = f'{text} • {props.bitrate}kbps' + # Fill audio bitrate info if available. + media = self._app.player.current_media + if media is not None and media.type_ == MediaType.audio: + props = media.props + if props.bitrate: + self._bitrate = props.bitrate + self.update_text() - self.setText(text) + def update_text(self): + if self._source: + text = f'{self._source} • {self._bitrate}kbps' + self.setText(text) + else: + self.setText(self.default_text) async def _switch_provider(self, provider_id): song = self._app.playlist.current_song diff --git a/feeluown/player/mpvplayer.py b/feeluown/player/mpvplayer.py index 9eebc3020a..7a23efd5ab 100644 --- a/feeluown/player/mpvplayer.py +++ b/feeluown/player/mpvplayer.py @@ -67,7 +67,8 @@ def __init__(self, _=None, audio_device=b'auto', winid=None, b'Mozilla/5.0 (Windows NT 10.0; Win64; x64)') #: if video_format changes to None, there is no video available - self.video_format_changed = Signal() + self.video_format_changed = Signal() # Optional[str] + self.audio_bitrate_changed = Signal() # Optional[int], for example: 128001 self._mpv.observe_property( 'time-pos', @@ -81,6 +82,10 @@ def __init__(self, _=None, audio_device=b'auto', winid=None, 'video-format', lambda name, vformat: self._on_video_format_changed(vformat) ) + self._mpv.observe_property( + 'audio-bitrate', + lambda name, bitrate: self._on_audio_bitrate_changed(bitrate) + ) # self._mpv.register_event_callback(lambda event: self._on_event(event)) self._mpv._event_callbacks.append(self._on_event) logger.debug('Player initialize finished.') @@ -259,6 +264,13 @@ def volume(self, value): super(MpvPlayer, MpvPlayer).volume.__set__(self, value) self._mpv.volume = self.volume + @property + def audio_bitrate(self): + """ + .. versionadded: 4.1.4 + """ + return self._mpv.audio_bitrate + @property def video_format(self): return self._video_format @@ -289,6 +301,9 @@ def _on_duration_changed(self, duration): def _on_video_format_changed(self, vformat): self.video_format = vformat + def _on_audio_bitrate_changed(self, bitrate): + self.audio_bitrate_changed.emit(bitrate) + def _on_event(self, event): event_id = event['event_id'] if event_id == MpvEventID.END_FILE: