参考:使用树莓派打造一个音乐播放器

(1)树莓派4B一个
(2)音箱一个

1 音乐播放器mtool安装

1.1 安装mtool

mtool是一个用python写的音乐播放器,在gitee和github上开源,主要用命令行进行控制。
下载地址:https://gitee.com/shadowlesswalker/mtool.git。

$ cd /usr/必须此目录
$ sudo git clone https://gitee.com/shadowlesswalker/mtool.git   mtool
$ cd mtool
$ sudo chmod 777 /usr/mtool/
$ sudo chmod 777 ./*赋予权限
$ sudo ln -s  /usr/mtool/mtoolctl   /usr/bin/mtoolctl
#创建软链接
$ sudo apt install python3-pygame安装依赖
$ pip3 install configparser安装依赖


mtool是一个C/S(服务器/客户端)模式的程序,服务器开启后会监听UDP端口(默认为127.0.0.1:6666),然后接受来自客户端的命令去控制播放。

1.2 使用mtool

1.2.1 修改配置文件mtool.conf

mtool使用配置文件./mtool.conf来设置默认的音量、播放列表、播放模式、端口等。

[player]
list = music   #默认播放列表,列表名必须出现在playlists节中
volume = 0.8   #默认音量
port = 6666    #服务器端口
index = 2      #当前播放文件索引(相对于当前播放列表)
next = next    #播放模式next|loop|random 分别对应顺序播放|单曲循环|随机播放[playlists]    #定义播放列表节,可设置多个列表,其名称必须唯一
music = music  #路径为./music/
en-listen = /var/share/en-listen

1.2.2 启动和关闭服务端

python3  /usr/mtool/mtool.py --server start
如果要在后台运行服务,执行命令:
$ nohup python3 /usr/mtool/mtool.py --server start > /usr/mtool/log 2>&1  &

0和1和2分别表示标准输入、标准输出和标准错误信息输出,可以用来指定需要重定向的标准输入或输出。
在一般使用时,默认的是标准输出1,将标准输出重定向到/usr/mtool/log。
2>&1 将错误信息重定向到标准输出。

(1)查看服务端状态

(2)关闭服务

$ kill -9 4033关闭服务
$ mtool -c exit关闭服务

注意添加完新的音乐文件后需要重启服务。

1.2.3 常用命令

mtool -c play  #播放
mtool -c play|pause|resume开始|暂停|继续播放
mtool -c stop停止播放
mtool -c vol=0.5   #设置音量
mtool -c lists  #查看可用的播放列表
mtool -c list     #列出当前播放列表中的音乐文件
mtool -c next=random|next|loop   #设置播放顺序
mtool -c playf=zui      #切换为单曲循环(next=loop),并且播放文件名中包含zui的文件

1.3 开机自动播放音乐

1.3.1 挂载U盘歌曲列表

(1)U盘开机自动被挂载
目录/media/pi/Linux Mint

当然也可以自己挂载后取消挂载

sudo mount /dev/sda4 /home/pi/mnt/windows挂载
sudo unmount /home/pi/mnt/windows取消挂载

(2)修改配置文件mtool.conf
根据自动挂载配置。

[player]
list = music3
volume = 0.4
port = 6666
index = 1011
next = random[playlists]
music = music
en-listen = /var/share/en-listen
music2 = /media/pi/Linux Mint/music
music3 = /media/pi/Linux Mint/mymusic

1.3.2 配置开机自启动

$ vim /home/pi/.bashrc

nohup python3 /usr/mtool/mtool.py --server start > /usr/mtool/log 2>&1  &

先手动启动服务端,虽然前面配置了开机自启动,但也只能下次开机才能生效。
$ source /home/pi/.bashrc

1.3.3 播放音乐

mtool -c play播放
mtool -c stop停止
mtool -c exit退出
mtool -c vol=0.5   #设置音量
source /home/pi/.bashrc
mtool -c exit

1.4 手机连接

可以在手机上安装ssh工具,比如JuiceSSH(推荐)。

1.5 异常解决


python运行文件是总会出现乱码问题,为了解决这个问题,在文件开头加上:python 字符编码的两种方式写法:

# coding=utf-8
或
# -*- coding:utf-8 -*-

2 设置树莓派定时播放

2.1 crontab语法

语法crontab [ -u user ] file
语法crontab [ -u user ] { -l | -r | -e }
其中
-e : 执行文字编辑器来设定时程表。
-r : 删除目前的时程表。
-l : 列出目前的时程表。

时间格式如下:f1 f2 f3 f4 f5 program
其中
f1 是表示分钟,
f2 表示小时,
f3 表示一个月份中的第几日,
f4 表示月份,
f5 表示一个星期中的第几天,
program 表示要执行的程序。

2.2 编写播放脚本

$ vim /usr/mtool/start-play-music.sh
$ sudo chmod 777 /usr/mtool/start-play-music.sh

#!/bin/bash
_dir="/usr/mtool"
mtool -c playlist=music #切换到music播放列表
mtool -c vol=0.5 #音量放到一半
mtool -c next=random #设置随机播放
mtool -c play #开始播放

2.3 添加定时任务

$crontab -e

10 17 * * * /usr/mtool/start-play-music.sh >> /usr/mtool/log     #每天下午17:10开始播放15 17 * * * mtool -c stop    #每天早上17:15停止播放

3 源码

# -*- coding:utf-8 -*-
'''
code by Shadow(山斗) from China.mtool(music tool) is a simple audio player mainly running on linux.
mtool is used with command line interface.you can control the player in your own code to play,stop musics.
mtool is C/S architecture program. it runs a UDP server at  the default port:127.0.0.1:6666 and receives commands from clients to control the player.
mtool use the config file ./mtool.conf .
In mtool.conf , you can set the default values like volume,playing order,default playlist in the player section,
and set some playlists in the playlists section.Each playlist is a path in which should include music files.'''import pygame
import time
import sys, getopt
from socket import *
import threading
import re
import configparser
import os
import random
_dir=os.path.dirname(os.path.abspath(__file__))
_conf_file=os.path.join(_dir,'./mtool.conf')print('hello from mtool by shadow')
mfile='./qiansixi.mp3'
isactive=True  #True to run server normally, False to quit Server
server_status='stopped' #stopped|playing|paused
mnext='stop'  #what to do for the next playing:stop|next|loop|randomvol=0.5 #volume
mlist=[]  #audio paths of current playlist
mindex=0  #index of playlist for next play
mport=6666 #Server UDP port
playlist_name='default' #current playlist name
playlist_path=os.path.join(_dir,'music')def loadlist(listname):'''load audios from a playlist,the palylist name must be specified in mtool.conf'''global mlist,mfile,playlist_name,playlist_pathlistpath=''conf=configparser.ConfigParser()conf.read(_conf_file)if listname in conf['playlists'].keys():playlist_name=listnameplaylist_path=conf['playlists'][playlist_name]if os.path.isabs(playlist_path)==False:playlist_path=os.path.join(_dir,playlist_path)else:print("invalid playlist name:%s"%(listname))returnif os.path.exists(playlist_path):mlist.clear()for iroot,idir,flist in os.walk(playlist_path):for f in flist:mlist.append(os.path.join(iroot,f))        else:print("playlist %s(%s) doesn't exist"%(listname,playlist_path))mindex=0if len(mlist)>0:mfile=mlist[0]print("load playlist %s(%s) from %s"%(listname,len(mlist),playlist_path))def _init():global mlist, vol, mport,mnextconf=configparser.ConfigParser()conf.read(_conf_file)vol=float(conf['player']['volume'])print("volume:%s"%(vol))mport=int(conf['player']['port'])mindex=int(conf['player']['index'])mnext=conf['player']['next']loadlist( conf['player']['list'])pygame.mixer.init()def play():global isactive,mfile,mlist,vol,mnext,mindex,server_statusif mnext=='loop':passelif mnext=='next':mindex=mindex+1if mindex >= len(mlist):mindex=0mfile=mlist[mindex]elif mnext=='random':mindex=random.randint(0,len(mlist)-1)mfile=mlist[mindex]try:print("vol:%s,next:%s,playing file %s"%(vol,mnext,mfile))    track=pygame.mixer.music.load(mfile)    pygame.mixer.music.set_volume(vol)pygame.mixer.music.play()server_status='playing'except Exception as e:print(e)def stop():global server_statusserver_status='stopped'pygame.mixer.music.stop()print('music stopped')def pause():global server_statusserver_status='paused'pygame.mixer.music.pause()print('music paused')
def unpause():global server_statusserver_status='playing'pygame.mixer.music.unpause()print('music resume')def _saveconfig():conf=configparser.ConfigParser()conf.read(_conf_file)conf['player']['volume']=str(vol)conf['player']['list']=playlist_nameconf['player']['next']=mnextconf['player']['index']=str(mindex)with open(_conf_file,'w') as f:conf.write(f)def command(opts,udpsvr=None,cltaddr=None):'''deal commands received from clients to control playing status'''global isactive, mnext, vol,mfilecmd=opts[0]response=Noneif cmd=='play':play()response="playing "+mfileelif cmd=='playi':try:i=init(opt[1])if i>=0 and i<len(mlist):mindex=iplay()except Exception as e:print(e)elif cmd=='playf':try:mfile=opts[1]if os.path.isabs(mfile)==False:for x in mlist:if mfile in os.path.basename(x):mfile=xmnext='loop'play()response="playing "+mfileexcept Exception as e:print(e)elif cmd=='stop':stop()elif cmd=='pause':pause()elif cmd=='resume':unpause()elif cmd=='vol':try:vol=float(opts[1])pygame.mixer.music.set_volume(vol)response="volume="+str(vol)_saveconfig()except Exception as e:print(e)elif cmd=='next':try:if opts[1] in ('loop','next','random','stop'):mnext=opts[1]response="next="+mnext_saveconfig()except Exception as e:print(e)elif cmd=='playlist':try:loadlist(opts[1])response="playlist=%s(%s,%s)"%(playlist_name,len(mlist),playlist_path)_saveconfig()except Exception as e:print(e)elif cmd=='info':if udpsvr and cltaddr:response="Server:Running\nnext=%s,vol=%s,status=%s\nplaylist=%s(%s,%s)\nfile=%s"%(mnext,vol,server_status,playlist_name,len(mlist),playlist_path,mfile)elif cmd=='lists':conf=configparser.ConfigParser()conf.read(_conf_file)response=''for x in conf['playlists']:response=response+'\n'+xelif cmd=='list':response=''for x in mlist:response=response+'\n'+xelif cmd=='saveconf':_saveconfig()elif cmd=='exit':isactive=False   response="server exitted"if response:udpsvr.sendto(response.encode('utf-8'),cltaddr)
def thcontrol():'''this function starts a UDP socket which binds at the port 127.0.0.1:6666 and receives commands to control the music playback. '''global isactive,vol,mportudpsvr=socket(AF_INET,SOCK_DGRAM)udpsvr.bind(('127.0.0.1',mport))print("server started and bind to 127.0.0.1:6666")while isactive:data,addr=udpsvr.recvfrom(1024)cmd=data.decode('utf-8')print("msg from %s :%s"%(addr,cmd))opts=re.split("=",cmd)        try:command(opts,udpsvr,addr)    except Exception as e:print(e)def sendcmd(cmd):global mportudpclt=socket(AF_INET,SOCK_DGRAM)udpclt.settimeout(1)udpclt.sendto(cmd.encode('utf-8'),('127.0.0.1',mport))try:data,addr=udpclt.recvfrom(1024)if data:msg=data.decode('utf-8')print('Server Response:\n'+msg)except Exception as e:passdef _notify():'''loop to check the status of playing'''try:if pygame.mixer.music.get_busy()==0:if mnext!='stop' and server_status=='playing':play()        except Exception as e:print(e)if isactive:t=threading.Timer(2,_notify)t.start()def main(argv):global isactivetry:opts, args = getopt.getopt(argv,"hc:",["server=","test"])  except getopt.GetoptError:print('-h  //help information')        exit(1)if len(opts)==0:print('hello from mtool by shadow')exit(0)for opt,arg in opts:if opt=='--server' and arg=='start':print('starting server')_init()threading._start_new_thread(thcontrol,())elif opt=="-c":sendcmd(arg)exit(0)elif opt=='-h':print('--server start  //start server')print('-c info|play|pause|resume|stop|list|lists|exit|vol=0.5')print('-c playf=filename  //loop to play a music file')print('-c next=stop|loop|next|random')print('-c playlist=playlistname  //note that the playlistname must be specified in mtool.conf')exit(0)else:print('-h  //help information')exit(0)threading.Timer(2,_notify).start()while isactive:time.sleep(1)print('mtool exit')exit(0)if __name__=='__main__':main(sys.argv[1:])
else:pass

4 语音控制

python通过调用百度api实现语音识别

import os
# 播放
os.popen("/usr/bin/mtool -c play")
# 播放文件
os.popen("/usr/bin/aplay speech.wav")
# -*- coding:utf-8 -*-
import wave
import requests
import time
import base64
from pyaudio import PyAudio, paInt16
import os
''' 你的APPID AK SK  参数在申请的百度云语音服务的控制台查看'''
APP_ID = '237***29'
API_KEY = 'DRGC6L***hG5RsWOQZbC'
SECRET_KEY = 'OnCmaG9S***1GFq5nTnKEfukXQ'framerate = 16000  # 采样率
num_samples = 2000  # 采样点
channels = 1  # 声道
sampwidth = 2  # 采样宽度2bytes
filepath = 'speech.wav'def getToken(API_KEY, SECRET_KEY):base_url = "https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id=%s&client_secret=%s"host = base_url % (API_KEY, SECRET_KEY)res = requests.post(host)return res.json()['access_token']def save_wave_file(filepath, data):wf = wave.open(filepath, 'wb')wf.setnchannels(channels)wf.setsampwidth(sampwidth)wf.setframerate(framerate)wf.writeframes(b''.join(data))wf.close()def my_record(filepath):pa = PyAudio()stream = pa.open(format=paInt16, channels=channels,rate=framerate, input=True,frames_per_buffer=num_samples)my_buf = []t = time.time()print('正在录音...')while time.time() < t + 4:  # 秒string_audio_data = stream.read(num_samples)my_buf.append(string_audio_data)print('录音结束...')# 写入文件save_wave_file(filepath, my_buf)stream.close()def speech2text(file, token, dev_pid=1537):# 读取音频文件with open(file, 'rb') as f:speech_data = f.read()FORMAT = 'wav'RATE = '16000'CHANNEL = 1CUID = APP_IDSPEECH = base64.b64encode(speech_data).decode('utf-8')data = {'format': FORMAT,'rate': RATE,'channel': CHANNEL,'cuid': CUID,'len': len(speech_data),'speech': SPEECH,'token': token,'dev_pid': dev_pid}url = 'https://vop.baidu.com/server_api'headers = {'Content-Type': 'application/json'}print('正在识别...')r = requests.post(url, json=data, headers=headers)Result = r.json()print('识别完成')if 'result' in Result:return Result['result'][0]else:return Resultif __name__ == '__main__':while True:# 听到ding后一秒开始录音并识别os.popen("/usr/bin/aplay ding.wav")time.sleep(1)my_record(filepath)TOKEN = getToken(API_KEY,SECRET_KEY)result = speech2text(filepath, TOKEN)print(result)if "同学" in result:os.popen("/usr/bin/aplay dong.wav")time.sleep(1)if "打开音乐" in result:os.popen("/usr/bin/mtool -c play")if "关闭音乐" in result:os.popen("/usr/bin/mtool -c stop")time.sleep(5)

树莓派-3-制作音乐播放器+语音控制相关推荐

  1. 树莓派3B qt+mplayer制作音乐播放器(10)

    内容 树莓派3B qt+mplayer制作音乐播放器:播放.暂停.上一曲.下一曲,音量调节. 平台:树莓派+qt+mplayer 1.配置 qt安装见此: https://blog.csdn.net/ ...

  2. 基于Arduino Uno开发板制作音乐播放器

    基于Arduino Uno开发板制作音乐播放器 本文将基于Arduino开发板实现一个音乐播放器. 利用Arduino Uno读取sd卡模块中内存卡的音乐,传输信号到扬声器进行播放. 一.项目软硬件简 ...

  3. winform制作音乐播放器

    winform制作音乐播放器 本文利用C# 调用Windows自带的Windows Media Player 打造一款属于自己的音乐播放器,以供学习分享使用,如有不足之处,还请指正. 概述 Windo ...

  4. 用Python制作音乐播放器(下,含完整源代码)

    哈喽,大家不知道是上午好还是中午好还是下午好还是晚上好! 音乐播放器,大家应该不陌生吧!今天我们一起来学习如何用python制作音乐播放器.之所开头有一个"下",是因为我们以前已经 ...

  5. 用Python制作音乐播放器(上)

    用Python制作简单的音乐播放器 哈喽,大家不知道是上午好还是中午好还是下午好还是晚上好! 音乐播放器,大家应该不陌生吧!今天我们一起来学习如何用python制作音乐播放器.之所开头有一个" ...

  6. Android桌面小部件AppWidget:音乐播放器桌面控制部件Widget(3)

     Android桌面小部件AppWidget:音乐播放器桌面控制部件Widget(3) Android桌面小部件AppWidget比较常用的场景就是音乐播放器,音乐播放器虽然通常在后台播放,但需要 ...

  7. vue + element UI【实战】音乐播放器/语音条(内含音频的加载、控制,事件监听,信息获取,手机网页阴影的去除等技巧)

    相关技巧,详见注释 <template><!-- 音乐播放器 --><div class="container"><h2>{{ mu ...

  8. HTML+纯JS制作音乐播放器

    该篇文章会教你通过JavaScript制作一个简单的音乐播放器.包括播放.暂停.上一曲和下一曲. 阅读本文章你需要对HTML.CSS和Javascript有基本的了解. 话不多说,先上图. emmm. ...

  9. Android 音视频深入 十三 OpenSL ES 制作音乐播放器,能暂停和调整音量(附源码下载)...

    项目地址 https://github.com/979451341/OpenSLAudio OpenSL ES 是基于NDK也就是c语言的底层开发音频的公开API,通过使用它能够做到标准化, 高性能, ...

最新文章

  1. [HDU] Tr A
  2. python内置数据结构_Python基础知识2-内置数据结构(下)
  3. virtualbox+vagrant安装虚拟机
  4. 不让登陆_百万伙伴争代言 不让梦想咕咕叫 中国太保寿险公益活动提前117天汇聚300万颗爱心...
  5. vue 数值 拼接字符串_【Vue原理】Compile - 白话版
  6. yyds!Java 性能优化的 50 个细节(珍藏版)
  7. postgresql立式版本下载_Apache ShardingSphere 4.1.1版本正式发布
  8. 2020计算机应用模拟题,2020年函授本科计算机应用基础课后作业、模拟题及答案...
  9. 操作系统文件的物理结构(文件分配方式)
  10. cdr 表格自动填充文字_常平办公软件培训分享之word表格自动填充序号
  11. 今日“春分”,我們來場春天的“飛花令”吧
  12. java开发未来三年职业规划
  13. Android输入法官方SoftKeyboard示例解析
  14. leetcode 825. Friends Of Appropriate Ages
  15. 迷信自身专业者,守株待兔尔
  16. 三国志战略版:Daniel_吕玲绮分析
  17. centos7搭建DNS服务,CA字签证书
  18. 使用SoftICE破解Winzip8.0全攻略
  19. 两种WIFI定位方法
  20. 全球地名中英文对照表(A)

热门文章

  1. 网络蚂蚁与FlashGet的文件多线程下载原理
  2. 集成elastic-job分布式调度定时任务
  3. 融资预审复核 代码梳理
  4. 解决bat批处理输出乱码的问题
  5. manifest php,manifest让网页实现离线访问
  6. python安装arcpy_为arcpy安装pip
  7. 【元胞自动机】元胞自动机单车道交通流(时空图)【含Matlab源码 1681期】
  8. 安卓逆向小案例——某新闻APP请求头urlSign还原
  9. 使用正则表达式实现注册表单验证(包括下拉列表二级联动、密码显示和隐藏)...
  10. 浙大第五版概统复习提纲(前八章)