V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
cosven
V2EX  ›  Linux

PyQt5 听歌缓存 && FeelUOwn 更新贴

  •  1
     
  •   cosven ·
    cosven · 2015-11-22 21:37:12 +08:00 · 4732 次点击
    这是一个创建于 3078 天前的主题,其中的信息可能已经有所发展或是发生改变。
    ### FeelUOwn 更新贴

    [FeelUOwn]( https://github.com/cosven/FeelUOwn) 是一款为 Linux 专门开发的音乐软件。目前相当于一个第三方版的网易云音乐。`Python` `Qt` `Linux`

    旧贴 <http://v2ex.com/t/235214#reply33>;

    - 新增加了歌单缓存,歌曲信息缓存。
    - 修复一些已知的 bug

    歌曲缓存指日可待... `哭笑脸`

    > 对网速不好的朋友来说应该是个好消息.....

    截图来一发:

    ![v5.0alpha 截图]( http://7xnn7w.com1.z0.glb.clouddn.com/v5.0a.png)

    最后附一段 Python + PyQt5 边缓存边听歌的解决方案 demo 版: (也是费劲苦心... Google 都被我用坏了,最后终于写了个 demo)

    ```
    #! /usr/bin/env python3
    import sys
    import time

    from PyQt5 import QtWidgets
    from PyQt5.QtWidgets import *
    from PyQt5.QtMultimedia import *
    from PyQt5.QtGui import *
    from PyQt5.QtCore import *

    from _thread import start_new_thread
    from threading import Thread, RLock

    import requests
    import os


    # secret base
    mp3_url = 'http://m1.music.126.net/Gybpf5bX9zfNesjXxZl3qw==/2053887720715417.mp3'

    # chedan
    mp3_url = 'http://m2.music.126.net/7tEJKStKIbxKPVKw7urYkA==/6033020302257380.mp3'

    # liangzhu
    mp3_url = 'http://m2.music.126.net/Jx2_zeePijuCGjqGSgTGyw==/6656443395918618.mp3'

    global i
    i = 0

    def print_duration(duration):
    time_text = QTime(0, (duration / 60000) % 60, (duration/ 1000) % 60)
    print("duration:", time_text.toString("mm:ss"))

    def print_position(position):
    time_text = QTime(0, (position/ 60000) % 60, (position/ 1000) % 60)
    print('position:', time_text.toString("mm:ss"), i)

    def print_media_changed(media):
    print ("media changed")

    def print_buffer(status):
    print ('buffer', status)


    class QFileWithLock(QFile):
    def __init__(self, path):
    super().__init__(path)
    self.lock = RLock()
    self.use_lock = True

    def disable_lock(self):
    self.use_lock = False

    def enable_lock(self):
    self.use_lock = True

    def seek(self, pos):
    if self.use_lock:
    print('use lock')
    self.lock.acquire()
    flag = super().seek(pos)
    self.lock.release()
    else:
    flag = super().seek(pos)
    return flag

    def write_to_end(self, data):
    print ('write_to_end wait for lock')
    self.lock.acquire()
    print ('get lock')
    super().seek(self.size())
    data = super().write(data)
    self.lock.release()
    return data


    class Player(QObject):
    def __init__(self):
    super().__init__()
    self.player = QMediaPlayer(flags=QMediaPlayer.StreamPlayback)
    # self.player.positi onChanged.connect(print_position)
    self.player.durati onChanged.connect(print_duration)
    self.player.currentMediaChanged.connect(print_media_changed)
    self.player.bufferStatusChanged.connect(print_buffer)
    self.tmp_pos = 0

    def start(self):
    print('start')
    start_new_thread(self.async, ())
    time.sleep(2)
    self.player.setMedia(QMediaContent(), self.music)
    self.player.play()

    def async(self):
    global i
    self.res = requests.get(mp3_url, stream=True, timeout=1)
    self.music = QFileWithLock('temp.mp3')
    # self.music = QBuffer()
    flag = self.music.open(QIODevice.ReadWrite)
    for chunk in self.res.iter_content(1024000):
    print('i:', i, end='')
    self.player.pause()
    print ('file seek pos: ', self.music.pos(), end='')
    # self.music.seek(self.music.size())
    # self.music.write(chunk)
    self.music.write_to_end(chunk)
    print ('file seek pos: ', self.music.pos())
    self.player.play()
    i += 1

    print("finished")
    self.music.disable_lock()


    class Widget(QWidget):
    def __init__(self):
    super().__init__()
    self.player = Player()
    self.button = QPushButton('play', self)
    self.button.clicked.connect(self.player.start)

    app = QtWidgets.QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())
    ```
    25 条回复    2015-11-23 21:56:56 +08:00
    ehs2013
        1
    ehs2013  
       2015-11-22 21:46:58 +08:00
    PyQt 有关的东西你还敢用 MIT 授权……乖乖 GPLv3 要不转 PySide 吧
    ehs2013
        2
    ehs2013  
       2015-11-22 21:48:37 +08:00
    “ PyQt is dual licensed on all supported platforms under the GNU GPL v3 and the Riverbank Commercial License. Unlike Qt, PyQt is not available under the LGPL. You can purchase the commercial version of PyQt here. More information about licensing can be found in the License FAQ.”

    由于 GPL 的传染性,所以你的程序也必须是 GPL
    cosven
        3
    cosven  
    OP
       2015-11-22 21:52:42 +08:00
    Soga , 学习了,这 license 的确没有在意过...
    Phant0m
        4
    Phant0m  
       2015-11-22 22:03:33 +08:00 via iPhone
    界面真漂亮 赞一个
    hei1000
        5
    hei1000  
       2015-11-23 01:29:22 +08:00
    "Linux 专门开发的音乐软件"为啥有 Mac OS X 下的截图
    cosven
        6
    cosven  
    OP
       2015-11-23 02:02:25 +08:00
    @hei1000 因为本机是 mac ,所以为了方便自己,专门对 mac 做了点兼容....

    开发测试什么的都在 Ubuntu 虚拟里面跑的....
    hei1000
        7
    hei1000  
       2015-11-23 02:46:02 +08:00
    Fedora 下面太麻烦了,我到现在还没有安装去
    Arthur2e5
        8
    Arthur2e5  
       2015-11-23 03:47:32 +08:00
    @ehs2013 其实我一直很好奇,要是宣称自己的程序是基于一个假定的——只是和某 GPL 库吻合的—— ABI 或 API 构建的,那会怎样?例如吧, BSD libedit/editline 就能提供 readline 的不少 API ……

    具体到行为的话,就像对 C 只发编译到半路而没链接的 object 文件之类的…… Py 的话本身就没有显式的链接指定,所以管他呢。
    Arthur2e5
        9
    Arthur2e5  
       2015-11-23 03:52:56 +08:00
    @Arthur2e5 (这样算是个诡辩,毕竟直接变成了“不是我故意搞成地址空间不隔离的”)。嗯,似乎在 https://lists.debian.org/debian-legal/2004/11/msg00169.html 有人讨论了……其中有一句:

    > The important consideration is the high-level *intention* of the connection, including what the different parts actually *do*.
    Twinkle
        10
    Twinkle  
       2015-11-23 05:46:25 +08:00
    带带我 QvQ
    cosven
        11
    cosven  
    OP
       2015-11-23 08:11:22 +08:00 via Android
    @hei1000 是哪个库装不上呢,可以把错误信息贴出来。一起研究下...
    cosven
        12
    cosven  
    OP
       2015-11-23 08:12:23 +08:00 via Android
    @Twinkle 0.0
    leeoo
        13
    leeoo  
       2015-11-23 08:25:24 +08:00
    最近也在断断续续用 PyQt 写点东西,只是由于它的 License ,一直在等支持 Qt 5.x 的 PySide2 正式 release
    yangzh
        14
    yangzh  
       2015-11-23 08:29:33 +08:00 via iPhone   ❤️ 1
    @leeoo 可以考虑 python3 + pyotherside
    hei1000
        15
    hei1000  
       2015-11-23 09:48:54 +08:00 via Android
    @cosven 发完之后装上了,主要是 python 模块的问题, quamash 死活装不上,总是有 error code 1 的错误,后来我下载 quamash 源代码编译安装的
    hei1000
        16
    hei1000  
       2015-11-23 09:52:01 +08:00 via Android
    @hei1000 之前还有各种 python 版本以及模块的问题, fedora 包安装工具 dnf 里面的包名和 apt 里面的包名名字不一样
    lawlietxxl
        17
    lawlietxxl  
       2015-11-23 10:01:45 +08:00
    很像网易云音乐!好看
    cosven
        18
    cosven  
    OP
       2015-11-23 10:20:52 +08:00
    @hei1000

    今早装了个虚拟机试了下。界面可以运行,不能播放音乐,我不熟悉 feedora ,不知道怎样安装 gstreamer 这个库... 其他的依赖这四条命令都可以搞定了...

    sudo dnf install python3-pip
    sudo dnf install python3-qt5
    sudo pip3 install -r requirements.txt
    sudo pip3 install python3-xlib

    gstreamer 怎么装我还没搞清楚,可能要你们自己折腾下了。不是很熟悉 fedora...
    cosven
        19
    cosven  
    OP
       2015-11-23 10:22:17 +08:00
    @hei1000

    看来你已经装好了 gstreamer 这个库?求教程,我在 readme 上更新下.. ~
    hei1000
        20
    hei1000  
       2015-11-23 10:47:15 +08:00
    @cosven 因为我之前就安装过相关库, 说实话,我也无法列出在这里具体应该安装哪些 gstreamer 相关包,因为是播放多媒体要安装的,我安装系统之后就安装了, 这应该不是个问题,fedora 用户应该很容易 Google 出来, 我尝试了是 dnf 安装你列出的 gstreamer 相关包,但是说没找到,因为 dnf 里面和 apt 里面包文件名很多都不一样.

    我随便在网上找的以下列表,应该足够了
    sudo dnf install gstreamer1-plugins-good gstreamer1-plugins-ugly gstreamer1-plugins-bad-free gstreamer1-plugins-bad-free-extras gstreamer1-plugins-bad-freeworld gstreamer-plugin-crystalhd gstreamer-ffmpeg gstreamer-plugins-good gstreamer-plugins-ugly gstreamer-plugins-bad gstreamer-plugins-bad-extras gstreamer-plugins-bad-free gstreamer-plugins-bad-free-extras gstreamer-plugins-bad-nonfree gstreamer-plugins-bad-extras libmpg123 lame-lib

    首先要安装 http://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-stable.noarch.rpm http://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-stable.noarch.rpm repo 文件
    cosven
        21
    cosven  
    OP
       2015-11-23 12:39:49 +08:00
    @hei1000 Soga , 非常感谢
    ehs2013
        22
    ehs2013  
       2015-11-23 15:29:07 +08:00
    @Arthur2e5 我记得 API 没版权吧。另外就算是比较弱的 LGPL (Lesser GPL) 也是要求你把非 LGPL (闭源)部分的 object 文件可以让其他人使用其他版本的 LGPL 的那个库来链接的。
    fly3949
        23
    fly3949  
       2015-11-23 20:54:21 +08:00
    壁纸居然是言叶之庭 QAQ !赞
    Arthur2e5
        24
    Arthur2e5  
       2015-11-23 21:56:34 +08:00
    @ehs2013 你提到的那点正是 LGBL 宽松的地方啊……
    Arthur2e5
        25
    Arthur2e5  
       2015-11-23 21:56:56 +08:00
    @Arthur2e5 …… LGPL …………………………………………………………
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2881 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 14:32 · PVG 22:32 · LAX 07:32 · JFK 10:32
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.