在 Android 上播放 mp3?

Playing mp3 on Android?

我正在尝试为 Kivy 制作一个音频播放器作为个人项目,但是我注意到我的应用程序无法加载 mp3 音频。经过一番研究,它似乎与某些许可问题有关?在任何情况下,androids 当然仍然可以播放 mp3 文件,那么我该怎么做才能实现这一点?

就目前而言,我使用的是来自 kivy 的普通 SoundLoader() class。我认为我的 android 音频使用的是 sdl2,但我可能会弄错,因为我不确定在哪里检查它,我只记得在某个地方看到过它。我也尝试过更改 KIVY_AUDIO 环境变量,但它没有用(我假设我做错了什么)。

有没有人知道任何解决方法,因为我似乎找不到任何解决方法?

看看这个 playing an audio file

kivy SoundLoader class 有一些问题(例如,它在某些 mp3 文件中不能正确定位)。正如 Joey 提到的那样,jnius 可以访问的原始 android class 效果更好,而且对于您使用它的大多数歌曲文件(mp3、mp4、flac、waves 等)

我制作了两个可用的 classes,一个用于 android,它使用 jnius,另一个用于 windows(当然 android class 不在这里工作)。

您可能必须更新到最新的 kivy 并按照文档中的描述添加 gstreamer。 并且:kivy logger 在 android 上的 unicode 存在一些问题,并在打印时抛出异常。声音播放正常。如果异常让您烦恼,请删除 kivy.info 行。

#coding: utf-8

from kivy.core.audio import SoundLoader
from kivy.utils import platform 
from kivy.logger import Logger
import time

class MusicPlayerAndroid(object):
    def __init__(self):

        from jnius import autoclass
        MediaPlayer = autoclass('android.media.MediaPlayer')
        self.mplayer = MediaPlayer()

        self.secs = 0
        self.actualsong = ''
        self.length = 0
        self.isplaying = False

    def __del__(self):
        self.stop()
        self.mplayer.release()
        Logger.info('mplayer: deleted')

    def load(self, filename):
        try:
            self.actualsong = filename
            self.secs = 0
            self.mplayer.setDataSource(filename)        
            self.mplayer.prepare()
            self.length = self.mplayer.getDuration() / 1000
            Logger.info('mplayer load: %s' %filename)
            Logger.info ('type: %s' %type(filename) )
            return True
        except:
            Logger.info('error in title: %s' % filename) 
            return False

    def unload(self):
            self.mplayer.reset()

    def play(self):
        self.mplayer.start()
        self.isplaying = True
        Logger.info('mplayer: play')

    def stop(self):
        self.mplayer.stop()
        self.secs=0
        self.isplaying = False
        Logger.info('mplayer: stop')

    def seek(self,timepos_secs):
        self.mplayer.seekTo(timepos_secs * 1000)
        Logger.info ('mplayer: seek %s' %int(timepos_secs))


class MusicPlayerWindows(object):
    def __init__(self):
        self.secs = 0
        self.actualsong = ''
        self.length = 0
        self.isplaying = False
        self.sound = None

    def __del__(self):
        if self.sound:
            self.sound.unload()
            Logger.info('mplayer: deleted')

    def load(self, filename):
        self.__init__()
        if type(filename) == unicode: filename = filename.encode('utf-8') #unicode does not work ! 
        self.sound = SoundLoader.load(filename)    
        if self.sound:
            if self.sound.length != -1 :
                self.length = self.sound.length
                self.actualsong = filename
                Logger.info('mplayer: load %s' %filename)
                return True
            else:
                Logger.info ('mplayer: songlength = -1 ...')
        return False

    def unload(self):
        if self.sound != None:
            self.sound.unload()
            self.__init__ # reset vars

    def play(self):
        if self.sound:
            self.sound.play()
            self.isplaying = True
            Logger.info('mplayer: play')

    def stop(self):
        self.isplaying = False
        self.secs=0
        if self.sound:
            self.sound.stop()
            Logger.info('mplayer: stop')

    def seek(self, timepos_secs):
        self.sound.seek(timepos_secs)
        Logger.info('mplayer: seek %s' %int(timepos_secs))

def main():
    songs = [
        'f:\_mp3_\_testdir_\file of ☠☢☣.mp3', #insert songs here
        'f:\_mp3_\Patricks Mp3s\electro\Echotek - Freak Africa.mp3',
        'f:\_mp3_diverse_\Testsuite\flac\01 - Jam & Spoon - Stella (Jam & Spoon Mix).flac',
        'f:\_mp3_\P1\1Start\Hot Chip - boy from school.mp4'
        ]

    Logger.info ('platform: %s' %platform)

    if platform == 'win':
        mplayer = MusicPlayerWindows()
    elif platform == 'android':
        mplayer = MusicPlayerAndroid()
    else:
        exit()

    for s in songs:
        if mplayer.load(s): # checking load, seek
            mplayer.play()
            time.sleep(2)
            mplayer.seek(90)
            time.sleep(2)
            mplayer.stop()
            mplayer.unload()

        else:
            Logger.info ('cant load song: %s' %s)


if __name__ == '__main__':
    main()