Git Product home page Git Product logo

beslyric-for-x / beslyric-for-x Goto Github PK

View Code? Open in Web Editor NEW
372.0 11.0 55.0 3.44 MB

BesLyric-for-X 是一款操作简单、功能实用的歌词制作软件。我们开发此软件的目的是为了为广大网易云音乐云村村民提供一个良好的歌词制作体验。

License: GNU General Public License v3.0

C++ 95.16% QMake 1.48% C 0.36% CSS 3.00%
ffmpeg qt netease-cloud-music lrc netease-cloud-music-lrc

beslyric-for-x's Introduction

BesLyric-for-X

Badge Latest version Gitter BesLyric QQ 群

BesLyric-for-X

BesLyric-screenshots-page-main

简介

BesLyric-for-X 是一款操作简单、功能实用的歌词制作软件。云村的村民们能够在网易云风格的界面中获得良好的歌词制作体验。

本软件的设计和开发源自 BesLyric ,它只能运行在 Windows 中。为了 Linux 和 macOS 的用户,我们基于 Qt 框架开发了 BesLyric-for-X 。

经过测试,本软件可在下列操作系统中正常运行:

  • Linux (64-bit, glibc>=2.27, glib2<2.70):
    • Deepin:
      • 20.2
    • Ubuntu:
      • 18.04.6 (gnome-shell 3.28.4)
      • 20.04.2 (gnome-shell 3.36.4)
    • Debian:
      • 10.9 (gnome-shell 3.30.2)
      • 11.0 (gnome-shell 3.38.4)
    • CentOS:
      • 8.2.2004 (gnome-shell 3.32.2)
    • Fedora:
      • 32 (gnome-shell 3.36.1)
    • Manjaro:
      • 20.0.3 (xfdesktop 4.14.2)
  • macOS (64-bit):
    • 10.13.6 (17G65)
    • 10.14.6 (18G84)
    • 10.15.7 (19H2)
    • 11.1 (20C69)
    • 11.5.2 (20G95)
  • Windows (32-bit & 64-bit):
    • 7 (6.1.7600)
    • 8.1 (6.3.9600)
    • 10:
      • 21H1 (10.0.19043.1110)
    • 11:
      • 21H2 (10.0.22000.194)

经过测试,本软件可在使用下列显示设置的桌面环境中正常运行:

分辨率 DPI 缩放等级
2560x1440 (QHD) 100%
3840x2160 (4K UHD) 100%
3840x2160 (4K UHD) 200%
5120x2880 (5K UHD) 100%
5120x2880 (5K UHD) 200%

请访问这篇博文查看使用教程或可能遇到的问题。

BesLyric-for-X 所使用的程序图标来自 Netease Cloudmusic icons - OPPO Color OS Icons - Easyicon

开发说明

获取源代码

$ git clone --recurse-submodules https://github.com/BesLyric-for-X/BesLyric-for-X.git
$ #         \--------__--------/
$ #              Important!

环境

框架:

  • Qt 5.12.4+

操作系统:

工具链:

  • Linux: GCC 5+
  • macOS: Xcode 11+ (Command Line Tools (CLT) only)
  • Windows
    • MSVC 2017+
    • MinGW 7.3.0+

本项目依赖这些第三方库:

  • FFmpeg 4
  • SDL 2
  • OpenSSL 1.1.1

构建

请按照 BesLyric-for-X/BesLyric-for-X_Conf 进行开发环境的配置,再进行构建。

Linux 或 macOS

$ qmake && make

Windows

> qmake -before "B4X_DEP_PATH=C:\b4x-lib"

> nmake         # MSVC
> mingw32-make  # MinGW

部署与打包

请参考 .deploy-package 文件夹中的内容。

beslyric-for-x's People

Contributors

bensonlaur avatar pzhlkj6612 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

beslyric-for-x's Issues

建议歌词文件可以载入lrc文件

可能我觉得别的歌词文件不准确需要进行修改,或者已经有个差不多的文件进行简单改一下,希望能载入lrc歌词文件然后修改的时候直接覆盖原来的时间标签就好了

权限不足导致数据文件夹 data/ 创建失败

#59 有关。


现在, B4X 会将用户数据存储在程序所在目录下。如果程序运行目录不可写,创建data/目录的操作将会失败(报错“无法为配置创建目录”),进而在之后需要对data/目录进行操作时出错,使程序崩溃。在 macOS 上的崩溃报告为:

...
Exception Type:        EXC_BAD_ACCESS (SIGSEGV)
Exception Codes:       KERN_INVALID_ADDRESS at 0x0000000000000008
Exception Note:        EXC_CORPSE_NOTIFY

Termination Signal:    Segmentation fault: 11
Termination Reason:    Namespace SIGNAL, Code 0xb
Terminating Process:   exc handler [584]

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   com.yourcompany.Beslyric-for-X	0x00000001021f53d3 PageLyricList::OnCreateLrcListItem() + 83
1   org.qt-project.QtCore         	0x00000001052d5b85 0x1050ad000 + 2263941
2   org.qt-project.QtWidgets      	0x00000001044aecef 0x1043b5000 + 1023215
3   org.qt-project.QtWidgets      	0x00000001044aeb89 0x1043b5000 + 1022857
4   org.qt-project.QtWidgets      	0x00000001044afcbf QAbstractButton::mouseReleaseEvent(QMouseEvent*) + 271
...

在 Ubuntu 上的崩溃报告为:

$ gdb -q -nh Beslyric-for-X core
...
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x000000000043dd5a in QVector<LyricListItem>::isDetached (this=0x8)
    at ../../Qt5.9.8/5.9.8/gcc_64/include/QtCore/qvector.h:108
108	    inline bool isDetached() const { return !d->ref.isShared(); }
[Current thread is 1 (Thread 0x7f9313923b00 (LWP 2870))]
(gdb) bt
#0  0x000000000043dd5a in QVector<LyricListItem>::isDetached (this=0x8)
    at ../../Qt5.9.8/5.9.8/gcc_64/include/QtCore/qvector.h:108
#1  0x000000000043dc6d in QVector<LyricListItem>::detach (this=0x8)
    at ../../Qt5.9.8/5.9.8/gcc_64/include/QtCore/qvector.h:378
#2  0x0000000000470da2 in QVector<LyricListItem>::begin (this=0x8)
    at ../../Qt5.9.8/5.9.8/gcc_64/include/QtCore/qvector.h:205
#3  0x000000000046e2a5 in PageLyricList::OnCreateLrcListItem (this=0x1d85d70)
    at ../BesLyric-for-X/MiddleWidgets/PageLyricList.cpp:495
...

在 Windows 上的崩溃报告为(暂无标准格式):

Exception thrown: read access violation.

Call stack:
0 Beslyric-for-X.exe!QVector<LyricListItem>::begin() Line 204
1 Beslyric-for-X.exe!PageLyricList::OnCreateLrcListItem() Line 495
2 Qt5Core.dll!6a554dff()
...

for(LyricListItem& item: pCurrentLyricList->items)

pCurrentLyricList为空指针。

快速双击播放列表中的歌曲会卡死

Beslyric版本:3.1.0.0
测试环境:QT5.6 mingw32

当我多次点击歌词单列表的歌曲时,会出现卡死现象。
客户端也存在该情况
源码debug提示no data in list for 1e8 times access

播放进度条在没有播放歌曲或歌曲播放结束后不应该能被拖动

在没有播放歌曲,或歌曲播放结束后, sliderSong 能被拖动,我认为这会让用户对它的功能感到疑惑,于是在 #15 版本中( 02b6fbb )做了一些修改:

AdjustingPos = false 时,一旦拖动 sliderSong ,其值就会被置为 void BottomWidget::onSliderSongPressed() 记录的 sliderSongOriginalPos ,使其表现为“无法被拖动”:

https://github.com/Beslyric-for-X/Beslyric-for-X/blob/02b6fbbb7cbed429faa1503f9514e90bf57a132f/BottomWidgets/BottomWidget.cpp#L311-L327


由于上述修改将导致在制作歌词时, sliderSong 被拖动或按住时会停止移动,释放后直接跳到当前播放位置这个问题, #16 版本( 354e203 )修改了相关逻辑, void BottomWidget::onSliderSongMoved(int position) 不再为 sliderSong 赋值,此时 void BottomWidget::onSliderSongPressed() 中第 324 行的注释已与功能不符:

https://github.com/Beslyric-for-X/Beslyric-for-X/blob/354e203e63fb05764e4c7280cdc14fafd516fbe2/BottomWidgets/BottomWidget.cpp#L319-L329


如果要做到“没有播放歌曲,或歌曲播放结束后, sliderSong 不能被拖动”,就需要先修复 #17 ,再做相关修改。具体的代码可能我之后写到评论里,或者直接开 PR 。

不进行 seek ,从头播放 1 秒左右的噪音

这个问题可能作者也有研究过,但是到目前似乎还没有完全被解决。
我把我的发现放在这里,给以后(重新写代码时)做参考。


环境:

  • FFmpeg 4.2.1 on Windows 10 1903 / Ubuntu 18.04 / macOS 10.14
  • FFmpeg 4.0.1 on Windows 10 1903

我把刚测试出来的一个“解决方法”写在这里,稍后会补充探究过程。

PlayThread::initDeviceAndFfmpegContext()方法中,移除整个关于AVFormatContext->iformat->read_header(struct AVFormatContext *)的代码:

https://github.com/Beslyric-for-X/Beslyric-for-X/blob/0dee64a8834f1ba294b12f99fee97acc438ee500/Entities/MusicPlayer/musicPlayer.cpp#L391-L396

接着把PlayThread::generateAudioDataLoop()方法中的seekToPos(10)注释掉,然后运行程序,播放音乐,开头的噪音应该就会消失了。


然而我并不知道这背后的原理……

考虑优化界面设计

现有设计:

image

其中歌词单 设计为 “收纳盒子” 切换代价较大,且不易被用户发现


可以考虑参考网易云音乐的设计,直接将 “歌词单列表” 设计在左侧,和 “制作歌词”、“下载歌曲” 和 “下载歌词” 并列:

image

发布版本 v3.1.2

  • 功能
    • 音频处理与控制
      • #41 前 2 秒的噪音消失;
      • #42 移除对于SDL_INIT_TIMERSDL_INIT_VIDEO的初始化;
      • #46 使用计算出的缓冲区大小;
      • #47 #49 ( #23 ) 新的 BesSlider 和更好用的 MusicPlayer(感谢 @yujunjiex )。
    • 歌词制作
      • #67 ( #65 ) 避免大于音频当前播放时间的“提前毫秒数”使歌词时间戳为负(感谢 @ish-kafel )。
    • 文件处理
      • #28 修复含有“.”的歌曲文件的文件名不能被正确识别。
      • #81 ( #80 ) 修复载入LRC文件时,没有根据编码正确读取导致的乱码问题(感谢 山雀教主周半仙
    • 设置
      • #76 ( #75 ) #85 (#84 ) 使默认目录设置的更改立刻生效。
  • 界面
    • 主窗口
      • #45 使最大化窗口自适应屏幕可用区域。
    • 设置页面
      • #72 ( #71 ) 将同意“下载声明”的时间由 60 秒改为 30 秒。
  • 代码
    • 多线程
      • #30 (未实际解决问题)退出前结束ThreadLoginThreadCheckUpdate线程。
    • 数据类型
      • #73 消除时间相关存储类型不一致导致的 warning 。
    • 逻辑
      • #52 ( #51 ) 避免对未成功获取(未初始化)的AVPacket进行释放( macOS );
      • #70 ( #37 ) 注释对AVPacket的无用测试以避免段错误( macOS )。
    • 语法
      • #40 避免#include自身;
      • #50 在 Qt 5.8 以下版本中“实现”了QMouseEvent::setLocalPos
    • 格式
      • #55 整理部分 pri 项目文件。
  • 其他
    • 依赖
      • ( #27 #29 ) 替换为不依赖 MSVCR120.DLL 的 OpenSSL 库(感谢 @devilintheEden );
      • #36 移除显式指定使用Qt5Network(d)
      • #53 移除对 SDL2main 库的链接。
    • 开发
      • #57 使用DESTDIR变量分离二进制文件;
      • #58 使 Ubuntu 将输出文件识别为可执行程序。
      • #82 在 Release 模式下,默认不输出 qDebug() 的输出

安装程序附带的 OpenSSL 库或 VC++ 库可能需要调整

#27 有关。

可能由于缺少正确的 VC++ 环境导致程序附带的 OpenSSL 库(libeay32.dllssleay32.dll,版本 1.0.2.0)无法被加载,以致无法联网。

相关错误信息:

qt.network.ssl: QSslSocket: cannot call unresolved function SSLv23_client_method
qt.network.ssl: QSslSocket: cannot call unresolved function SSL_CTX_new
qt.network.ssl: QSslSocket: cannot call unresolved function SSL_library_init
qt.network.ssl: QSslSocket: cannot call unresolved function ERR_get_error
qt.network.ssl: QSslSocket: cannot call unresolved function ERR_get_error

获取 SSL 相关信息:

qDebug()<<QSslSocket().supportsSsl();
qDebug()<<QSslSocket().sslLibraryVersionNumber();
qDebug()<<QSslSocket().sslLibraryVersionString();
qDebug()<<QSslSocket().sslLibraryBuildVersionNumber();
qDebug()<<QSslSocket().sslLibraryBuildVersionString();
false
0
""
268443791
"OpenSSL 1.0.2h  3 May 2016"

如果环境正确:

true
268443663
"OpenSSL 1.0.2 22 Jan 2015"
268443791
"OpenSSL 1.0.2h  3 May 2016"

测试环境:

系统名称 NT Build
Windows 7 Ultimate Service Pack 1 6.1.7601.24214.amd64fre.win7sp1_ldr_escrow.180801-1700
Windows 10 Pro 6.3.18362.1.amd64fre.19h1_release.190318-1202
文件名 SHA1
Setup-BesLyric-3.1.1.0.exe A2CC8561B36D01128CE1B9993685379F3DC71304
Beslyric-for-X.exe E32160D19A636055AD19752C4B301CD53EEDC60E
libeay32.dll 0098A723A358B92B62B1E51845DEC2D2B58DBCBB
ssleay32.dll 7911856DE1A9E3025B8828AA29F6BEE5A8BF8D9D
qt-opensource-windows-x86-msvc2015-5.7.1.exe 7A9F611D620CB21FE634421A748DA61377827156

把从 https://indy.fulgan.com/SSL/ 找到的相同版本的 OpenSSL 库文件与 Beslyric-for-X 附带的库文件通过 Dependency Walker 对比:

  [   ]  ADVAPI32.DLL
  [   ]  BCRYPTPRIMITIVES.DLL
  [   ]  CRYPTBASE.DLL
  [   ]  GDI32.DLL
  [   ]  KERNEL32.DLL
  [   ]  KERNELBASE.DLL
  [   ]  LIBEAY32.DLL
+ [   ]  MSVCR120.DLL
  [   ]  MSVCRT.DLL
  [   ]  NTDLL.DLL
  [   ]  RPCRT4.DLL
  [   ]  SECHOST.DLL
  [   ]  SSPICLI.DLL
  [   ]  USER32.DLL
  [   ]  WIN32U.DLL
  [   ]  WS2_32.DLL

Setup-BesLyric-3.1.1.0.exe中的 OpenSSL 库文件有对Visual C++ 2013 可再发行组件包中的MSVCR120.DLL的依赖。

所以要解决问题,就需要在 BesLyric 的安装包里带上 32 位的MSVCR120.DLL

安装包:

我自己提取的:

msvcr120_dll.zip(SHA1: 51B994C006DAB4CEFC337BA845852911A4ACF5FC)
| - msvcr120_12.0.21005.1.dll(SHA1: F19E9D8317161EDC7D3E963CC0FC46BD5E4A55A1)
\ - msvcr120_12.0.40660.0.dll(SHA1: B2D5A8B5C0FD735038267914B5080AAB57B78243)

经测试,使用任一版本的MSVCR120.DLL均可,但建议使用新版本的。


注意:Qt 5.7.1 中的 Qt Creator 4.2.0 所在文件夹中有相同的 OpenSSL 库文件,但我并没有发现放在一起的 VC++ 运行库,不清楚 Qt Creator 是怎么使用它们的。

macOS 10.14 窗口位置、最大化窗口位置问题

仅在 macOS 10.14 下测试。

前提条件

  • 窗口的 border 大于 0 。

窗口非最大化时

  • 情况一,如果(窗口高度 + 一个 border 距离) >= (屏幕高度 - 菜单栏高度)
    • 窗口顶部最多可以比菜单栏底部高出(窗口高度 + 一个 border 距离) - (屏幕高度 - 菜单栏高度)
  • 情况二,如果(窗口高度 + 一个 border 距离) < (屏幕高度 - 菜单栏高度)
    • 窗口无法拖动至紧贴菜单栏——最多只能移动到菜单栏向下一个 border 距离的位置。

*窗口最大化时

  • 窗口底部与屏幕底部之间有一个 border 距离(现在为 8 ,下同)的空隙,同时窗口顶部比菜单栏底部高出一个 border 距离,窗口顶部被部分遮挡,此时窗口高度 == (屏幕高度 - 菜单栏高度)
    • 此时,将窗口底部边框向上或向下拉,会使窗口顶部与菜单栏之间出现小于等于一个 border 距离的空隙,而窗口底部与屏幕底部之间依然有一个 border 距离的空隙,此时0 < [(屏幕高度 - 菜单栏高度) - 窗口高度] <= 两个 border 距离
  • 已最大化的窗口无法通过双击“标题栏”、单击“最大化/恢复”按钮恢复原大小;
    • 可以手动调整各边框以改变窗口大小(同时也可以拖动窗口以便调整边框)。
  • 实际上,窗口最大化是一个特例,它满足窗口高度 == (屏幕高度 - 菜单栏高度)(这个等式前文已提到),也就是“窗口非最大化时”的情况一。

*屏幕分辨率变化时

  • 窗口不自动调整大小,因此:
    • 从高分辨率变为低分辨率时,标题栏可能超过菜单栏以致无法调整窗口位置,参考“窗口非最大化时”情况一;
    • 从低分辨率变为高分辨率时,参考“窗口非最大化时”情况二。
    • 经测试,QApplication::primaryScreen()&QScreen::availableGeometryChanged信号似乎没有在屏幕分辨率变化时发出。

macOS 10.14+ seek 或重新播放时 PlayerThread 崩溃

环境

  • macOS 10.14 (18A391) / 10.15.3 (19D76)
  • VMware Workstation 15.5.0 build-14665864 / 15.5.1 build-15018445
  • Unlocker 3.0.3 * from paolo-projects
  • FFmpeg 4.2.2
  • SDL 2.0.10

seek 时崩溃

报告(部分):

...

Crashed Thread:        11  PlayThread

Exception Type:        EXC_BAD_ACCESS (SIGSEGV)
Exception Codes:       KERN_INVALID_ADDRESS at 0x0000000000000018
Exception Note:        EXC_CORPSE_NOTIFY

Termination Signal:    Segmentation fault: 11
Termination Reason:    Namespace SIGNAL, Code 0xb
Terminating Process:   exc handler [12053]

...

Thread 11 Crashed:: PlayThread
0   com.yourcompany.Beslyric-for-X	0x0000000107496a99 packet_queue_flush(PacketQueue*) + 73 (musicPlayer.cpp:120)
1   com.yourcompany.Beslyric-for-X	0x0000000107498847 PlayThread::generateAudioDataLoop() + 1159 (musicPlayer.cpp:605)
2   com.yourcompany.Beslyric-for-X	0x0000000107497214 PlayThread::run() + 196 (musicPlayer.cpp:279)
3   org.qt-project.QtCore         	0x000000010a426fd3 0x10a405000 + 139219
4   libsystem_pthread.dylib       	0x00007fff6a2bf33d _pthread_body + 126
5   libsystem_pthread.dylib       	0x00007fff6a2c22a7 _pthread_start + 70
6   libsystem_pthread.dylib       	0x00007fff6a2be425 thread_start + 13

...

重新播放时崩溃

...

Crashed Thread:        4  PlayThread

Exception Type:        EXC_BAD_ACCESS (SIGSEGV)
Exception Codes:       KERN_INVALID_ADDRESS at 0x0000000000000018
Exception Note:        EXC_CORPSE_NOTIFY

Termination Signal:    Segmentation fault: 11
Termination Reason:    Namespace SIGNAL, Code 0xb
Terminating Process:   exc handler [622]

...

Thread 4 Crashed:: PlayThread
0   com.yourcompany.Beslyric-for-X	0x000000010475d2b9 packet_queue_flush(PacketQueue*) + 73 (musicPlayer.cpp:120)
1   com.yourcompany.Beslyric-for-X	0x000000010475f74c PlayThread::clearContextAndCloseDevice() + 124 (musicPlayer.cpp:627)
2   com.yourcompany.Beslyric-for-X	0x000000010475eaa8 PlayThread::ReleaseAll() + 56 (musicPlayer.cpp:663)
3   com.yourcompany.Beslyric-for-X	0x000000010475d933 PlayThread::run() + 211 (musicPlayer.cpp:259)
4   org.qt-project.QtCore         	0x0000000107e7aba9 QThreadPrivate::start(void*) + 329
5   libsystem_pthread.dylib       	0x00007fff634a4e65 _pthread_start + 148
6   libsystem_pthread.dylib       	0x00007fff634a083b thread_start + 15

...

可能的解决方案

检查packet_queue_flush(PacketQueue *q)

https://github.com/Beslyric-for-X/Beslyric-for-X/blob/0dee64a8834f1ba294b12f99fee97acc438ee500/Entities/MusicPlayer/musicPlayer.cpp#L113-L133

移除对pkt1->pkt.data的测试,或者增加对pkt1的空指针测试,问题不再出现:

-       if(pkt1->pkt.data != (uint8_t *)"FLUSH")
+       if(pkt1 != nullptr && pkt1->pkt.data != (uint8_t *)"FLUSH")
        {
            ;
        }

截至目前,这个问题在 Windows 7 / 10 、 Ubuntu 18.04 上都未曾出现过。

播放进度条的逻辑需要重新整理

有一个办法能找到部分与 sliderSong 有关的问题:(使用当前最新版本 04b7dae

https://github.com/Beslyric-for-X/Beslyric-for-X/blob/04b7dae4f8fdddd93a4e0e8b2a8cd69a4a19192e/BottomWidgets/BottomWidget.cpp#L118


修改 setNotifyInterval(int) 参数的值,使 m_positionUpdateTimer 的周期较现在的长,例如 500 (原来是 33 );

进行歌词制作,在播放时拖动 sliderSong ,能发现 sliderSong 在被不断置为当前播放位置。


减小 setNotifyInterval(int) 参数的值,例如 5 ;

在歌曲播放时暂停,拖动并释放 sliderSong ,如果时间正好,其会在原位置继续显示一段时间。

同时我也做了验证,在 m_positionUpdateTimer 周期很短的情况下,我在 9827fab 的修改实际上是没有作用的,即无论处在播放还是暂停状态,拖动并释放 sliderSong 后其均会在原位置继续显示一段时间。


这个问题的解决能帮助 #20



现在有好几个关于 sliderSong 的问题了,这些是在实际使用时影响不大,但逻辑上的确需要修改的地方。

Segmentation fault (Linux)

如题,运行./Beslyric-for-linux.sh,得到以下报错:

链接目录:/home/xin/Software/Beslyric-for-linux/.:/home/xin/Software/Beslyric-for-linux/Beslyric-for-linux-deployed
Segmentation fault

Linux版本:Debian 9.5

从歌词单到歌词预览界面切换步骤太繁琐

场景说明

  • 要预览制作好的lrc歌词

操作步骤

  1. 点击进入 歌词单 功能
  2. 歌词单列表 中双击一首歌曲播放
  3. 点击右上角按钮切换回主界面
  4. 点左下角歌曲封面进入歌曲播放界面,预览歌词

1

问题说明

从歌词单界面播放歌曲到查看到歌词,操作繁琐。界面上虽然尽量和网易云音乐保持风格一致,但考虑到这款工具只用来制作歌词,可以认为工具只有三个功能:

  1. 下载歌曲、歌词
  2. 制作歌词
  3. 播放歌曲并预览歌词

而查看歌词单到预览歌词是个关联性很强的操作,应当减少切换界面导致的操作步骤,用着会更舒服一些。

建议方案

可以考虑在歌词界面时,左下角仍然保持歌曲区域显示,可以直接点击歌曲封面切换到预览歌词

image

Ubuntu 18.04 窗口无法拖动到屏幕范围以外

仅在 Ubuntu 18.04 (GNOME Shell 3.28.2) 下测试。

程序的窗口无法拖到屏幕外——最多只能移动到屏幕可用区域(除了顶栏、任务栏以外的区域)边缘向内一个 border 距离(现在为 8 )的位置。
不过,双屏时能够跨越屏幕正常拖动。

歌词单 页面内鼠标指针样式未及时还原

环境:

BesLyric 3.1.1.0
Windows 7 SP1、Windows 10


有问题的区域如图:

a

这个区域由三个矩形交成(坐标从BesFramelessWidget::mouseMoveEvent(event->pos())取得),如下表:

矩形区域 左上坐标 右下坐标
A (7, 72) (258, 662)
B (258, 72) (358, 323)
C (296, 110) (542, 357)

表现的效果为:

在 歌词单 页面,在界面之外,从左侧移动鼠标进入界面,能看到鼠标指针变为水平方向箭头(Qt::SizeHorCursor)后并未及时还原。只要鼠标在上述范围内,就会一直保持箭头样式,直到移出该范围,或单击鼠标左键,才能还原。如果按住鼠标左键,从 歌词单 页面内拖动到程序窗口外再拖动回来,则不会出现前述现象。


我的分析和猜测:

  • 区域 C 容易理解,因为有“前景”控件,所以BesFramelessWidget不响应鼠标的非单击移动事件;
  • 区域 A 的代码我还没能找到;
  • 区域 B 可能是布局的错误?
  • 在单击鼠标左键(或按住左键拖动)后鼠标样式正常,猜测与setMouseTracking()相关的逻辑存在问题。

考虑移除 -Wno-deprecated-declarations

项目配置中有如下 qmake 指令:

unix:!macx{

#消除ffmpeg中对使用旧接口的警告
QMAKE_CXXFLAGS += -Wno-deprecated-declarations

}

现阶段,在 Qt 5.14.1 下对项目进行构建时会产生 90 个-Wdeprecated-declarations,同时还会产生 92 个其它警告(主要来自一些与“ mp3Editor ”有关的文件)。
我个人认为可以在其它警告所指出的问题被解决过半后,移除-Wno-deprecated-declarations,以跟上新特性的步伐。


相关资料:

#47 版本依然存在进度条闪回的问题

#47 版本依然存在“播放时拖动进度条后释放进度条闪回音频当前位置”的问题,不过出现概率极低:

BottomWidget::positionChanged => sliderSong->value()= 866 position 188813
BottomWidget::positionChanged => sliderSong->value()= 866 position 188839
BottomWidget::positionChanged => sliderSong->value()= 866 position 188865
BottomWidget::positionChanged => sliderSong->value()= 866 position 188891
BesSlider::mousePressEvent(QMouseEvent *ev), enableMouseEvt= true
BesSlider::mousePressEvent() old value: 866
handle clicked
click_pos_offset: QPoint(5,-1)
void BottomWidget::onSliderSongPressed() sliderSong->value()= 866  musicPlayer->state()= 1
BesSlider::mousePressEvent() new value: 866
BesSlider::mouseMoveEvent:  QPoint(582,7)
handle hovering
void BottomWidget::onSliderSongMoved(int position= 863 )
BesSlider::mouseMoveEvent:  QPoint(577,7)
...
handle hovering
void BottomWidget::onSliderSongMoved(int position= 286 )
BesSlider::mouseReleaseEvent ev->pos() QPoint(194,13) 286
void BottomWidget::onSliderSongReleased() sliderSong->value()= 286  posAdjust= 62323
seek successful     from  190145  to around: 62323
to  190171
BottomWidget::positionChanged => sliderSong->value()= 286 position 190171        <--- boom
BottomWidget::positionChanged => sliderSong->value()= 872 position 62328
BottomWidget::positionChanged => sliderSong->value()= 286 position 62354
BottomWidget::positionChanged => sliderSong->value()= 286 position 62380
BottomWidget::positionChanged => sliderSong->value()= 286 position 62407

开 issue 是因为 PR 已合并,回顾的时候容易忽略掉。

希望支持切换文件名命名格式

一直习惯使用 歌手 - 歌曲名 的格式保存歌曲,而此工具默认为 歌曲名 - 歌手 的格式,且不支持切换。
因此有些不合习惯,希望可以增加选项以支持切换命名格式。

网易云音乐设置中的 音乐命名格式 选项:
image

对于播放条的修改出错

抱歉。我在 #12 中对 sliderSong 的 seek 相关代码修改有错,导致 sliderSong 和 labelTimeCurrent 的功能出现问题。

重现:

git checkout 9827fabc294a08533d01c83e27122fbc99475664

不播放任何歌曲,拖动并释放 sliderSong , sliderSong 回到起始位置, labelTimeCurrent 为 -35791:-23.-648 ,表示拿到了没有初始化的 position ;日志输出 positionChanged(int position= -2147483648 ) ,表示 m_positionUpdateTimer 已在工作。


对比:

git checkout d33f89a93a279d43c76f0237b738fdb5d2d2de4a 回到前一个提交,并在 void BottomWidget::positionChanged(int position) 方法下添加 qDebug()<<"void BottomWidget::positionChanged(int position= "<<position<<" )";

不播放任何歌曲,拖动并释放 sliderSong , sliderSong 停留在释放时的位置, labelTimeCurrent 为 00:00.000 ,不输出 positionChanged(int position) ,表示 m_positionUpdateTimer 没有工作。


我将尽快修复。

网络访问出错时,提示单一,容易造成用户的困惑

问题发现起始于 检测更新 功能 的实施。
网络更新功能会去查询:LINK_LAST_VERSION_INFO (根据平台不同而改变,比如 windows 平台的 https://files-cdn.cnblogs.com/files/BensonLaur/lastVersion-windows.zip ),当文件被我删除时,程序直接提示 ”无法连接网络“,这个会挺困惑的
image

原因是程序访问网络接口仅仅根据 reply->error()==QNetworkReply::NoError 返回 true 和 false
https://github.com/Beslyric-for-X/Beslyric-for-X/blob/6d7b30239525a91e027fb750d399effe0c632b7e/Utility/NetAccess.cpp#L44

更理想的设计应该是返回更多的错误细节

可以考虑直接使用 网络错误码枚举作为返回值

enum NetworkError {
        NoError = 0,

        // network layer errors [relating to the destination server] (1-99):
        ConnectionRefusedError = 1,
        RemoteHostClosedError,
        HostNotFoundError,
        TimeoutError,
        OperationCanceledError,
        SslHandshakeFailedError,
        TemporaryNetworkFailureError,
        NetworkSessionFailedError,
        BackgroundRequestNotAllowedError,
        TooManyRedirectsError,
        InsecureRedirectError,
        UnknownNetworkError = 99,

        // proxy errors (101-199):
        ProxyConnectionRefusedError = 101,
        ProxyConnectionClosedError,
        ProxyNotFoundError,
        ProxyTimeoutError,
        ProxyAuthenticationRequiredError,
        UnknownProxyError = 199,

        // content errors (201-299):
        ContentAccessDenied = 201,
        ContentOperationNotPermittedError,
        ContentNotFoundError,
        AuthenticationRequiredError,
        ContentReSendError,
        ContentConflictError,
        ContentGoneError,
        UnknownContentError = 299,

        // protocol errors
        ProtocolUnknownError = 301,
        ProtocolInvalidOperationError,
        ProtocolFailure = 399,

        // Server side errors (401-499)
        InternalServerError = 401,
        OperationNotImplementedError,
        ServiceUnavailableError,
        UnknownServerError = 499
    };
    Q_ENUM(NetworkError)

这样 0(NoError )表示访问成功,其他表示访问出错

添加对 Flac 后缀名文件支持

因为是 ffmpeg 编码器进行解码,是否可以对 Flac 文件的支持?
实测在不转换编码只是简单更改后缀名之后,可以正常解码文件。

首句歌词时间戳异常

刚做了一首歌,音乐一开始就是第一句歌词,在默认提前300ms的情况下,最终生成第一句的时间戳为[-909387743:51.524],导致需要手动修改。希望可以给首句时间加个判断,小于0就插入[00:00.000]

Mac版预览时cpu占用率高达100%以上,导致风扇不停转

cpu占用率过高会导致风扇呼呼不停的转,原因是预览时,左侧的那个模拟磁盘转动导致的,就连网易云音乐本身也会这样,但网易云音乐提供了开关,关了就不会转动,所以希望 BesLyric-for-X 也可以提供一个开关。

3.1版本播放音乐有杂音

你好,感谢你开源并分享这么好用的歌词制作软件,使用过程中发现3.1版本发现有很严重的杂音,同样的音乐在旧版上不会出现杂音,希望能够修复

不在开始制作歌词时播放音频

不在开始制作歌词时播放音频,为一些歌词靠前的音乐,或者为歌词中非歌词的必要信息(艺术家等)留出制作时间。

Windows av_dump_format 无法及时、正常输出

注意,本 issue 提到的所有问题仅在 Windows 7 / 10 出现。在 Ubuntu 18.04.4 和 macOS 10.15.3 ,这些问题是不存在的。


av_dump_format()方法的可能的调用栈:

现在的问题是:

  1. Windows 下需要设置av_log_set_level(AV_LOG_DEBUG)及以上(AV_LOG_DEBUG为 48),才能最终看到av_dump_format()的输出(之前也提到过: #39 (comment) );
  2. 第 1 点说的“最终”,是因为av_dump_format()的信息需要在一次 seek 或者整个播放器退出后才会被输出。

进一步说:

  1. av_dump_format()调用av_log()时传递的信息级别为AV_LOG_INFO (32) ,小于等于默认的AV_LOG_INFO (32)(可由av_log_get_level()获取),按理说应该被输出(而不被av_log_default_callback()中的判断忽略掉);
  2. 在第 1 点的基础上,不能立刻输出,我猜测可能是锁机制在起作用,而且这个锁与 FFmpeg 的AVMutex mutex有冲突;
  3. 之前没有发现这个问题,是因为在每次开始播放音频时都会进行一次 seek ,而这个 seek 在 #41 被移除了,问题才得以暴露出来。

用处不大的小实验:

  1. 直接调用av_log()欲输出字符串,现象与av_dump_format()相同;
  2. 写了一个简单的调用qDebug()输出的方法,并将其指针传给void av_log_set_callback(void (*callback)(void*, int, const char*, va_list))方法。调用av_dump_format()时,信息立刻被输出了。

挺多地方不喜欢

最近用的软件LyricEditor忽然播放不了音乐了,想试一下这软件,但是发现这软件只是界面比较好看,主要功能还不如一个几千行wpf软件好用,歌词只能看到提前的两句,遇到rap全看对词熟不熟,加载lrc竟然把时间轴当作文本了,也不加一个去除时间轴功能。

精力都花在做UI上了

播放进度条在制作歌词暂停时不应该能被拖动

使用当前最新版本 04b7dae ,在制作歌词时暂停, sliderSong 可以被拖动并释放到任意位置,继续播放会使其跳到当前播放位置。

#8 提到,不支持在制作歌词时进行 seek 操作,所以在制作模式下 sliderSong 应该表现为“完全无法被拖动”,或者在之后实现在制作时也能 seek 。


制作歌词时, bInMakingMode = trueAdjustingPos = falsevoid BottomWidget::positionChanged(int position) 持续更新 sliderSong 位置。

制作中暂停时,不再自动更新位置,由于 void BottomWidget::onSliderSongMoved(int position) 中的处理不完整,就能拖动并释放 sliderSong 到任意位置。

将用户数据移动到程序所在目录之外

现阶段, B4X 各版本均把用户数据存储在程序所在目录下,这不利于调试程序(切换 debug / release 、切换构建套件或 distclean 后)、升级版本时对于数据的保留。

我建议使用 QStandardPaths 进行改良。
其好处是,能保证程序所在目录的干净以及用户数据的独立性;
可能造成的问题是,如果不同版本间的数据不兼容,就需要在程序中做处理。

另外,如果已将用户数据移动到程序所在目录之外,就可以考虑提供“清除用户数据”和“导出用户数据”的功能。其中“导出用户数据”功能的实现效果可以为“使用类似资源管理器的程序定位到用户数据所在文件夹”(在 Windows 上为explorer /select,"path")。

macOS 10.14 Ubuntu 18.04 开始播放时 AudioQueue thread 崩溃

版本: 9c51e31

环境:

  • macOS 10.14 (18A391)
  • FFmpeg 4.2.2
  • VMware Workstation 15.5.1 build-15018445
  • Unlocker 3.0.3 * from paolo-projects

报告(部分):

...

Crashed Thread:        8  AudioQueue thread

Exception Type:        EXC_CRASH (SIGABRT)
Exception Codes:       0x0000000000000000, 0x0000000000000000
Exception Note:        EXC_CORPSE_NOTIFY

Application Specific Information:
abort() called
Beslyric-for-X(838,0x700002cc5000) malloc: *** error for object 0xb00007f9209e675c: pointer being freed was not allocated


Thread 6:: PlayThread
0   libsystem_kernel.dylib        	0x00007fff5ca06876 __semwait_signal + 10
1   libsystem_c.dylib             	0x00007fff5c991830 nanosleep + 199
2   libSDL2-2.0.0.dylib           	0x0000000110abb861 SDL_Delay_REAL + 83
3   com.yourcompany.Beslyric-for-X	0x000000010e807078 PlayThread::generateAudioDataLoop() + 168 (musicPlayer.cpp:529)
4   com.yourcompany.Beslyric-for-X	0x000000010e805e54 PlayThread::run() + 196 (musicPlayer.cpp:255)
5   org.qt-project.QtCore         	0x0000000111797fd3 0x111776000 + 139219
6   libsystem_pthread.dylib       	0x00007fff5cabc33d _pthread_body + 126
7   libsystem_pthread.dylib       	0x00007fff5cabf2a7 _pthread_start + 70
8   libsystem_pthread.dylib       	0x00007fff5cabb425 thread_start + 13

Thread 8 Crashed:: AudioQueue thread
0   libsystem_kernel.dylib        	0x00007fff5ca08b86 __pthread_kill + 10
1   libsystem_pthread.dylib       	0x00007fff5cabec50 pthread_kill + 285
2   libsystem_c.dylib             	0x00007fff5c9721c9 abort + 127
3   libsystem_malloc.dylib        	0x00007fff5ca806e2 malloc_vreport + 545
4   libsystem_malloc.dylib        	0x00007fff5ca804a3 malloc_report + 152
5   libavutil.56.dylib            	0x0000000110887189 av_freep + 21
6   com.yourcompany.Beslyric-for-X	0x000000010e807a7f PlayThread::fillAudio(void*, unsigned char*, int) + 143 (musicPlayer.cpp:684)
7   libSDL2-2.0.0.dylib           	0x0000000110ab6c3b outputCallback + 188
8   com.apple.audio.toolbox.AudioToolbox	0x00007fff2e152870 ClientAudioQueue::CallOutputCallback(AudioQueueBuffer*) + 260
9   com.apple.audio.toolbox.AudioToolbox	0x00007fff2e150ccb AQClientCallbackMessageReader::DispatchCallbacks(void const*, unsigned long) + 179
10  com.apple.audio.toolbox.AudioToolbox	0x00007fff2e13c04f ClientAudioQueue::FetchAndDeliverPendingCallbacks(unsigned int) + 291
11  com.apple.audio.toolbox.AudioToolbox	0x00007fff2e13bebd AQCallbackReceiver_CallbackNotificationsAvailable + 121
12  com.apple.audio.toolbox.AudioToolbox	0x00007fff2e13bc3e _XCallbackNotificationsAvailable + 33
13  com.apple.audio.toolbox.AudioToolbox	0x00007fff2e13ba4c mshMIGPerform + 230
14  com.apple.CoreFoundation      	0x00007fff2f848959 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 41
15  com.apple.CoreFoundation      	0x00007fff2f8488b7 __CFRunLoopDoSource1 + 527
16  com.apple.CoreFoundation      	0x00007fff2f830945 __CFRunLoopRun + 2574
17  com.apple.CoreFoundation      	0x00007fff2f82fce4 CFRunLoopRunSpecific + 463
18  libSDL2-2.0.0.dylib           	0x0000000110ab69f3 audioqueue_thread + 931
19  libSDL2-2.0.0.dylib           	0x0000000110a50a2b SDL_RunThread + 60
20  libSDL2-2.0.0.dylib           	0x0000000110ab2d1a RunThread + 9
21  libsystem_pthread.dylib       	0x00007fff5cabc33d _pthread_body + 126
22  libsystem_pthread.dylib       	0x00007fff5cabf2a7 _pthread_start + 70
23  libsystem_pthread.dylib       	0x00007fff5cabb425 thread_start + 13
  
...

截至目前,这个问题在 Windows 7 / 10 、 Ubuntu 18.04 上都未曾出现过。


另外我想知道的是, Windows 和 Ubuntu 上关于程序崩溃的报告,像 macOS 这样比较详细的,能在哪里找到呢? Beslyric-for-X 有时会在切歌后直接崩溃,我没能找到日志,难以分析。

能否加入双语字幕

能否加入双语字幕?有些歌曲会有双语字幕,但是应用里下载的只能是单语言

计时器在歌曲播放结束后未停止,播放进度条和时间标签交互不正常

这是一直存在的问题:

歌曲播放结束后, labelTimeCurrent 不归零, sliderSong 回到初始位置,拖动 sliderSong 会使在其初始位置和拖动位置之间闪动。


重现:

git checkout 354e203e63fb05764e4c7280cdc14fafd516fbe2 回到 #16 版本;

播放一首歌曲(我使用的歌曲长度为 137012 ms ),当其播放结束,日志输出:

BottomWidget::positionChanged => audioOriginalPos= 136960  sliderSong->value()= 996
BottomWidget::positionChanged => audioOriginalPos= 137012  sliderSong->value()= 997
ending reached
&PlayThread::audioFinish bIsLock= false
void BottomWidget::onAudioFinished(bool isEndWithForce= false )
BottomWidget::positionChanged => audioOriginalPos= 137012  sliderSong->value()= 997
&PlayThread::finished bIsLock= true
BottomWidget::positionChanged => audioOriginalPos= 137012  sliderSong->value()= 0
BottomWidget::positionChanged => audioOriginalPos= 137012  sliderSong->value()= 0
...

labelTimeCurrent 保持 02:17.012 , sliderSong 不断被设置到初始位置。


查看代码:

https://github.com/Beslyric-for-X/Beslyric-for-X/blob/354e203e63fb05764e4c7280cdc14fafd516fbe2/BottomWidgets/BottomWidget.cpp#L273-L286

注意到 sliderSong 在播放结束后被置为 0 ( musicPlayer->duration() == 0 成立), labelTimeCurrent 被置为 position (由 showPosition(int) 处理)。


查找调用:

https://github.com/Beslyric-for-X/Beslyric-for-X/blob/354e203e63fb05764e4c7280cdc14fafd516fbe2/StackFrame/MainWidget.cpp#L249-L253

https://github.com/Beslyric-for-X/Beslyric-for-X/blob/354e203e63fb05764e4c7280cdc14fafd516fbe2/StackFrame/MainWidget.cpp#L117

https://github.com/Beslyric-for-X/Beslyric-for-X/blob/354e203e63fb05764e4c7280cdc14fafd516fbe2/Entities/MusicPlayer/musicPlayer.cpp#L1004-L1008

https://github.com/Beslyric-for-X/Beslyric-for-X/blob/354e203e63fb05764e4c7280cdc14fafd516fbe2/Entities/MusicPlayer/musicPlayer.cpp#L796

这表明,在歌曲播放结束后 m_positionUpdateTimer 仍在工作, BottomWidget::positionChanged(int position) 被反复调用。


能找到停止 m_positionUpdateTimer 并发送 0 位置的代码:

https://github.com/Beslyric-for-X/Beslyric-for-X/blob/354e203e63fb05764e4c7280cdc14fafd516fbe2/Entities/MusicPlayer/musicPlayer.cpp#L907-L917

但是目前 void MusicPlayer::stop() 方法只在制作歌词时被触发:

https://github.com/Beslyric-for-X/Beslyric-for-X/blob/354e203e63fb05764e4c7280cdc14fafd516fbe2/StackFrame/MainWidget.cpp#L97-L98

注意,该 connect 写在了 MainWidget 类里。


修复本问题需要整理 PlayThread 和 MusicPlayer 等类的逻辑;

因为从用户体验来说这并不是致命的,所以不需要太优先。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.