使用kivy实现声音播放,看似简单实则有坑, 又是柿子翻阅大量外网资料后刨坑总结。
播放音频可以使用他的SoundLoader组件,简单两行就可以实现声音播放。如果你只是在PC端运行那么照抄以下代码就可以了
PC端播放
from kivy.network.urlrequest import UrlRequest
path="./sound/apple.wav" # 可以是本地文件, 也可以是网址http://XXX/apple.wav,也可以是mp3
b=SoundLoader.load(filename=path) # 载入文件
b.play() # 播放声音
移动端播放本地文件
但是如果你想要在Android上进行本地声音播放,需要注意下面的问题:
1、目前Kivy只支持 wav格式
2、在打包APK的时候需要注意修改相关的参数,在打包环境中输入 buildozer init 生成初始化参数表,不知道怎么用buildozer怎么打包的,请先看buildozer 打包 APK 的教程。找到下面的参数把wav 加进去。 Linux 环境下可以用vim 打开文件进行编辑
3、下面两端都要改不要漏了,这两段不是连着的
# (list) Source files to include (let empty to include all the files)
source.include_exts = py,png,jpg,kv,atlas,wav
# (list) List of inclusions using pattern matching
source.include_patterns = assets/*,images/*.png,sound/*.wav
移动端播放网页音频/服务器音频
但是如果你想要在Android上进行网页/服务器后端声音播放,需要注意下面的问题:
Kivy 的播放器不支持流媒体!!!!,所以需要下载后再播放
这里我创建了一个下载按钮一个播放按钮,点击玩下载后等一会儿,再点击播放按钮就可以播放声音了,效果如下
python 主程序代码供参考
这里会看到 Import os 和 from android.permissions import 注意 android 这个包是不需要安装的,在 Buildozer 和 P4a里自带的,只有在android端才能生效。所以需要先判断系统环境
另外同时需要对spec 文件修改
main.py 主程序代码如下,
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.app import App
from kivy.network.urlrequest import UrlRequest
from kivy.core.audio import SoundLoader
from kivy.utils import platform
#import requests
import os
if platform == "android":
from android.permissions import request_permissions, Permission
request_permissions([Permission.READ_EXTERNAL_STORAGE, Permission.WRITE_EXTERNAL_STORAGE])
url="http://106.14.124.112:8080/download_voice_en/apple.wav"
# 构建窗口按钮,一个下载按钮,一个播放按钮
kv = Builder.load_string("""
#:import utils kivy.utils
<test>:
name:"test"
BoxLayout:
Button:
text: "download"
on_release:root.buttonClicked()
Button:
text: "apple"
on_release:root.sound()
""")
class test(Screen):
def buttonClicked(self):
a= UrlRequest(url, file_path='apple.wav')
print("done download")
def sound(self):
b=SoundLoader.load(filename='./apple.wav')
b.play()
print("done sound")
sm = ScreenManager() # 创建窗口管理器
screens = [test(name="test")]
for screen in screens: # 为每一个窗口生成容器
sm.add_widget(screen)
class ScreenApp(App):
def build(self):
return sm
ScreenApp().run()
spec 文件中需要修改 permission,获取网络及读写权限
# (list) Permissions
android.permissions = INTERNET,WRITE_EXTERNAL_STORAGE,READ_EXTERNAL_STORAGE