-
Notifications
You must be signed in to change notification settings - Fork 55
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
新的 BesSlider 和更好用的 MusicPlayer #47
Merged
BensonLaur
merged 13 commits into
BesLyric-for-X:master
from
pzhlkj6612:new_slider_and_better_player
Jan 18, 2020
Merged
新的 BesSlider 和更好用的 MusicPlayer #47
BensonLaur
merged 13 commits into
BesLyric-for-X:master
from
pzhlkj6612:new_slider_and_better_player
Jan 18, 2020
Conversation
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
It seems that the responding speed of the audio playing has been improved.
It seems that `read_header()` in av_format.h is the source of the noise.
branch name: remove_useless_initialization_of_SDL_subsystem
The "PlayThread's logic" are the functions `audio_decode_frame()` and `packet_queue_get()`. 1. `audio_clock` will store the position in millisecond and `qint64` type. 2. the 1e8 times attempts is NOT ok. 3. `packet_queue_get()` should return `-1` if something goes wrong.
This makes the BUG more visible.
1. New `BesSlider` 1.1. Click is on the handle 1.1.1. The relative position between the mouse and the center of handle (`click_pos_offset`) is calculated and stored when the handle is dragged. So the handle will move relative to the mouse and keep a certain offset (`click_pos_offset`) instead of placing its center under the mouse. This is a Netease Music style. 1.2. Click is NOT on the handle 1.2.1. Use `BesSliderStyle` to change the positioning method from 'stepping' to 'directness'. 1.2.2. The new positioning method makes the click-and-drag operation can be performed correctly, because `QSlider::sliderPressed`, `QSlider::sliderMoved` and `QSlider::sliderReleased` signals will be emitted correctly when the click is not on the handle. 1.3. "Where is my mouse ?" 1.3.1. Use `subControlRect` to determine the range of handle and whether the mouse is over the handle. 1.3.2. Remove old logic related to the above, including `enterEvent(QEvent*)` and `leaveEvent(QEvent*)` functions. 1.3.3. Set `setMouseTracking(true)`. As long as `enableMouseEvt` is equal to `true`, whether or not the mouse is pressed, when the mouse hovers over the handle, its cursor style will be `Qt::PointingHandCursor`, otherwise it will be `Qt::ArrowCursor` (set by `unsetCursor()`). 2. `BottomWidget` and `MusicPlayer` 2.1. About the refined logic 2.1.1. Even if only the handle of `sliderSong` is clicked, the seeking operation will be performed. `audioOriginalPos` is dead. This is a Netease Music style. 2.1.2. Existing logic restricts clicks to be performed on `sliderSong` only when `enableMouseEvt` is equal to `true`, so the redundant judgments have been removed. 2.2. The position of the audio is playing 2.2.1. `AdjustingPos` will be set `true` when `sliderSong` is pushed down. 2.2.2. `MusicPlayer` will tell `BottomWidget` and `AdjustingPos` will be set `false` when the seeking operation is finished (`PlayThread::seekFinished()` and `MusicPlayer::seekFinished()`). 2.2.3. So, It's guaranteed that the current position will only be refreshed by `MusicPlayer` if no mouse action is applied to `sliderSong`.
1. `BottomWidget` will reset `AdjustingPos` to `false` and ready for next seeking operation. 2. End the player by setting `AGSStatus` to `AGS_FINISH`.
1. Any interval of the timer is unreasonable. Higher values send too many indentical positions, while lower values make the positions inaccurate. 2. Now when the `PlayThread::audio_decode_frame()` function is called, `PlayThread` will notify `MusicPlayer` to send the position. 3. `PlayThread::positionChanged()` signal does not contain the value of the current position. 4. When `MusicPlayer` receives the signal `PlayThread::positionChanged()`, the `MusicPlayer::sendPosChangedSignal()` function will be called. 5. The `MusicPlayer::positionChanged(qint64)` signal contains the position which obtained from `playThread->getCurrentTime()`. 6. The pause-and-play operation of the timer in function `MusicPlayer::seek(quint64)` is useless and misleading.
1. If the player is paused, this call is useless.
1. Implement the keeping pause after seeking. 2. When the player is paused, the new position should be sent on time after a seeking which is performed by the program.
1. The function `av_seek_frame()` will get error with `AVSEEK_FLAG_ANY` method, especially when somebody wants to seek to the end of the audio. 2. So, the player will try seeking again with `AVSEEK_FLAG_BACKWARD` method.
pzhlkj6612
force-pushed
the
new_slider_and_better_player
branch
from
January 11, 2020 08:24
bd73dab
to
21e6074
Compare
BensonLaur
reviewed
Jan 18, 2020
This comment has been minimized.
This comment has been minimized.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
简述
本 PR 重写了
BesSlider
和相关界面逻辑,解决了播放进度条在使用上的主要问题。本 PR 还修改了部分播放逻辑,试图让程序运行得更好(properly)。本 PR 试图解决 #12 、 #13 、 #15 、 #16 、 #17 、 #19 、 #20 、 #21 、 #23 、 #31 、 #32 、 #38 、 #39 、 #41 和 #42 中提到或遗留的问题。
本 PR 在 Ubuntu 18.04 / Windows 10 1903 / macOS 10.14[1] 测试通过。
详细内容
1. 移除前 2 秒的噪音
来自 #41 。
2. 不初始化
SDL_INIT_TIMER
和SDL_INIT_VIDEO
子系统来自 #42 。
3. 判定音频到达尾部的更好的方法
在 #38 (comment) 提到。
4. 移除 1 亿(1e8)次尝试并修改了
audio_decode_frame()
和packet_queue_get()
中的逻辑在 #23 和 #38 提到。
本 PR 对于 #23 和 #38 的解决不完全,特别是 #38 (comment) 提到的问题,这可能需要重新设计
PlayThread
。4.1. 移除 1 亿(1e8)次尝试
对于音频是否到达尾部有更好的方法,见上文。
4.2. 修改
audio_decode_frame()
和packet_queue_get()
这部分修改是以我自己的理解来做的,目的是修 BUG,并且让逻辑更清楚。但目前我还没有掌握 FFmpeg 的基本用法,所以可能有不合理之处。
PacketQueue
的第一个AVPacket
包是nullptr
,同时block
置为false
,那么packet_queue_get()
将会返回-1
。audio_decode_frame()
都将返回-1
。m_MS.audio_clock
将以qint64
类型存储当前音频位置的毫秒时间。相关的方法的形参类型、返回值类型也做了修改,但尽量把影响控制在最小范围——数据类型的统一之后再说。5. 使用新的
BesSlider
并对BottomWidget
和MusicPlayer
做适配由 #32 改良。
5.1. 新的
BesSlider
click_pos_offset
,这样,手柄就会相对于鼠标保持一定的偏移量进行运动,而不是把自己的中心放到鼠标下方。这是 网易云音乐 的风格。BesSliderStyle
改变定位方式,原来是“步进”,现在是“直接”。QSlider::sliderPressed
、QSlider::sliderMoved
和QSlider::sliderReleased
信号将会被正确地发送。subControlRect
确定手柄的范围,进而确定鼠标是否在手柄上。enterEvent(QEvent*)
和leaveEvent(QEvent*)
方法在内的旧逻辑被移除了。setMouseTracking(true)
。当enableMouseEvt
置为true
时,无论鼠标是否按下,当鼠标悬停在手柄上时,它的指针样式都将为Qt::PointingHandCursor
,否则将为Qt::ArrowCursor
(由unsetCursor()
设置)。5.2. 对
BottomWidget
和MusicPlayer
做适配audioOriginalPos
。这是 网易云音乐 的风格。enableMouseEvt
置为true
时对sliderSong
的点击才有效,所以冗余的判断被移除了。sliderSong
被按下时,AdjustingPos
将被置为true
。MusicPlayer
将会通过信号MusicPlayer::seekFinished()
和MusicPlayer::seekError()
通知BottomWidget
,AdjustingPos
将被置为false
。sliderSong
时,音频的当前位置才能被MusicPlayer
刷新。6. 移除
m_positionUpdateTimer
并通过audio_decode_frame()
发出位置变化的信号PlayThread::audio_decode_frame()
被调用时,PlayThread
将会提醒MusicPlayer
以发送新的音频位置。PlayThread::positionChanged()
信号不包含当前位置的值。MusicPlayer
收到PlayThread::positionChanged()
信号时,MusicPlayer::sendPosChangedSignal()
方法将会被调用。MusicPlayer::positionChanged(qint64)
信号包含了由playThread->getCurrentTime()
获得的位置。MusicPlayer::seek(quint64)
方法中关于定时器的操作是无用且有误导性的(在 在 seek 时移除多余的对定时器的操作 #31 提到)。7. 当
PlayThread
处于AGS_SEEK
状态时不进行pauseDevice()
和playDevice()
7.1. 移除
pauseDevice()
如果本身是在暂停状态下,这个调用就是多余的。
7.2. 移除
playDevice()
实现“暂停时 seek 后继续暂停”。
在暂停时,通过代码(programmatically)进行 seek 后,音频位置将会即时刷新。
8. 提供回退 seek
av_seek_frame()
使用AVSEEK_FLAG_ANY
方式进行 seek 时可能会出错,特别是 seek 到音频末尾附近时。AVSEEK_FLAG_BACKWARD
方式再 seek 一次。脚注
1. ^ macOS 需要 #37 。