Source

VPlayer / player_phonon.py

Full commit
# -*- coding: utf-8 -*-

from time import sleep

from PyQt4 import QtCore
from PyQt4.phonon import Phonon

from logger import log
from source_phonon import Source

class Player(QtCore.QThread):
    def __init__(self):
        QtCore.QThread.__init__(self)
        log.info('Initializing Phonon player')
        self.audio = Phonon.AudioOutput(Phonon.MusicCategory, self)
        self.media = Phonon.MediaObject(self)
        self.path = Phonon.createPath(self.media, self.audio)
        self.connect(self.media, QtCore.SIGNAL("stateChanged(Phonon::State, Phonon::State)"),
             self.stateChanged)
        self.connect(self.media, QtCore.SIGNAL("finished()"), self.stop)
        self.connect(self.media, QtCore.SIGNAL("tick(qint64)"), self.tick)
        self.media.setTickInterval(500)
        self.new_track = False
        self.percent = 0
        self.track = None
        self.src = None

    def get_bitrate(self):
        if not self.track.local:
            if hasattr(self, 'src'):
                while not self.src.buf.length and not self.src.buf.failed:
                    sleep(0.1)
                filesize = self.src.buf.length * 8
                rate = float(filesize) / self.track.length / 1024
                rates = [64, 128, 192, 256, 320]
                for srate in rates:
                    if abs(srate-rate)<10:
                        rate = srate
                        break
                rate = round(rate)
                self.track.filesize = filesize / 8
                return rate

    def tick(self, time):
        if self.track:
            if self.new_track:
                rate = self.get_bitrate()
                self.emit(QtCore.SIGNAL('bitrate'), rate)
                self.new_track = False
            self.emit_time()

    def emit_time(self):
        current = self.media.currentTime()
        total = self.media.totalTime()
        if current < 0 or total < 0:
            current = total = 0
        if not total:
            return
        self.percent = current*100/total
        self.emit(QtCore.SIGNAL("time"), (current, total))

    def stateChanged(self, now, was):
        states = { 0 : 'LoadingState',
                   1 : 'StoppedState',
                   2 : 'PlayingState',
                   3 : 'BufferingState',
                   4 : 'PausedState',
                   5 : 'ErrorSate'}
        log.debug('Phonon\'s state changed from %s to %s' % (states[was], states[now]))
        was = states[was]
        now = states[now]
        if now in ('StoppedState', 'ErrorState'):
            self.stop()
            self.emit(QtCore.SIGNAL('status'), ("end", self.track, self.percent))

    def play_track(self, track, volume):
        self.stop()
        self.set_volume(volume)
        self.track = track
        self.track.set_playing(True)
        self.new_track = True
        self.src = Source(track)
        self.src.open(QtCore.QIODevice.ReadOnly)
        self.mediasrc = Phonon.MediaSource(self.src)
        self.media.setCurrentSource(self.mediasrc)
        self.media.play()
        self.emit(QtCore.SIGNAL('status'), ('start', track))
        log.debug('!!! track should play NOW')

    def control(self, state):
        if state == 'pause':
            self.pause()
        if state == 'stop':
            self.stop()

    def seek(self, pos):
        self.media.seek(self.media.totalTime() * pos / 100)

    def stop(self):
        self.media.stop()
        self.media.clearQueue()
        if self.src:
            self.src.stop()
        if self.track:
            self.track.set_playing(False)
            self.track.set_paused(False)

    def pause(self):
        if self.media.state() == Phonon.PausedState:
            self.media.play()
            if self.track:
                self.track.set_paused(False)
                self.track.set_playing(True)
                self.emit(QtCore.SIGNAL('status'), ('unpause', self.track))
        if self.media.state() in (Phonon.PlayingState, Phonon.LoadingState):
            self.media.pause()
            if self.track:
                self.track.set_paused(True)
                self.track.set_playing(True)
                self.emit(QtCore.SIGNAL('status'), ('pause', self.track))
        self.emit_time()

    def set_volume(self, value):
        self.audio.setVolume(float(value)/100)