Kivy和audiostream,无法录制

Kivy and audiostream, can't record

我正在使用 audiostream 但无法通过麦克风录制任何内容。

def mic_callback(buf):
    print('got', len(buf))
    frames.append(buf)
    print('size of frames: ' + len(frames))

def bcallback(instance):
    mic = get_input(callback=mic_callback, source='mic')
    mic.start()
    #mic.poll()
    time.sleep(5)
    mic.stop()

class MyApp(App):
    def build(self):
        btn1 = Button(text='Audio Record')
        btn1.bind(on_press=bcallback)
        return btn1

if name == 'main':
    MyApp().run()

运行 这段代码并使用 logcat 我可以看到 mic_callback 不起作用,因为 logcat 上没有任何打印。

我也试过将源更改为 default,但也没有用。

我有一个代码片段,用于使用 kivy 在 android 上进行录音。 我没有使用音频流,但也许它对您有用。 不幸的是,它没有以 wav 格式录制,而你 需要安装 jnius 才能使用代码段。

在 Player() 和 Recorder() 中传递给 play() 和 start() 的按钮只是一个字符串,其中包含 Player() 和 Recorder() 正在访问的文件的名称。

import os
from jnius import autoclass

if not os.path.isdir("/sdcard/kivyrecords/"):
    os.mkdir("/sdcard/kivyrecords/")

PATH = "/sdcard/kivyrecords/rec{0}.mp4"

class Player(object):
    def __init__(self):
        # get the MediaPlayer java class
        self.MediaPlayer = autoclass('android.media.MediaPlayer')

    def play(self, button):
        # create our player
        mPlayer = self.MediaPlayer()
        mPlayer.setDataSource(PATH.format(button))
        mPlayer.prepare()
        mPlayer.start()
        if not mPlayer.isPlaying():
            mPlayer.release()

class Recorder(object):
    def __init__(self):
        # get the needed Java classes
        self.MediaRecorder = autoclass('android.media.MediaRecorder')
        self.AudioSource = autoclass('android.media.MediaRecorder$AudioSource')
        self.OutputFormat = autoclass('android.media.MediaRecorder$OutputFormat')
        self.AudioEncoder = autoclass('android.media.MediaRecorder$AudioEncoder')

        self.mRecorder = self.MediaRecorder()       

    def start(self, button):
        self.mRecorder.setAudioSource(self.AudioSource.MIC)
        self.mRecorder.setOutputFormat(self.OutputFormat.MPEG_4)
        self.mRecorder.setOutputFile(PATH.format(button))
        self.mRecorder.setAudioEncoder(self.AudioEncoder.HE_AAC)
        self.mRecorder.prepare()

        self.mRecorder.start()

    def stop(self, button):
        time.sleep(0.5)
        self.mRecorder.stop()
        self.mRecorder.release()
        self.mRecorder = self.MediaRecorder()   

编辑:

整个脚本:

#qpy:kivy
'''
Created on 20.06.2015

@author: jan
'''
import kivy
kivy.require('1.0.7') # replace with your current kivy version !

from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout        

#from kivy.core.audio import SoundLoader 

from jnius import autoclass

import os
import time

if not os.path.isdir("/sdcard/kivyrecords/"):
    os.mkdir("/sdcard/kivyrecords/")

PATH = "/sdcard/kivyrecords/rec{0}.mp4"

class Player(object):
    def __init__(self):
        # get the MediaPlayer java class
        self.MediaPlayer = autoclass('android.media.MediaPlayer')

    def play(self, button):
        # create our player
        mPlayer = self.MediaPlayer()
        mPlayer.setDataSource(PATH.format(button))
        mPlayer.prepare()
        mPlayer.start()
        if not mPlayer.isPlaying():
            mPlayer.release()

class Recorder(object):
    def __init__(self):
        # get the needed Java classes
        self.MediaRecorder = autoclass('android.media.MediaRecorder')
        self.AudioSource = autoclass('android.media.MediaRecorder$AudioSource')
        self.OutputFormat = autoclass('android.media.MediaRecorder$OutputFormat')
        self.AudioEncoder = autoclass('android.media.MediaRecorder$AudioEncoder')

        self.mRecorder = self.MediaRecorder()       

    def start(self, button):
        self.mRecorder.setAudioSource(self.AudioSource.MIC)
        self.mRecorder.setOutputFormat(self.OutputFormat.MPEG_4)
        self.mRecorder.setOutputFile(PATH.format(button))
        self.mRecorder.setAudioEncoder(self.AudioEncoder.HE_AAC)
        self.mRecorder.prepare()

        self.mRecorder.start()

    def stop(self, button):
        time.sleep(0.5)
        self.mRecorder.stop()
        self.mRecorder.release()
        self.mRecorder = self.MediaRecorder()       

PLAY = Player()
REC = Recorder()
RECORDED = {1 : False, 2 : False, 3 : False, 
                        4 : False, 5 : False, 6 : False,
                        7 : False, 8 : False, 9 : False}

class MyGrid(GridLayout):
    def __init__(self):
        super(MyGrid, self).__init__(cols=3, rows=3)

        global REC
        global RECORDED
        global PLAY

        for i in range(1, 10):
            b = Button(text=str(i))
            b.bind(on_press=self.recorplay)
            b.bind(on_release=self.stop)
            self.add_widget(b, i)

    def recorplay(grid, button):
        if not RECORDED[int(button.text)]:
            REC.start(button.text)
        else:
            PLAY.play(button.text)

    def stop(grid, button):
        if not RECORDED[int(button.text)]:
            REC.stop(button.text)   
            RECORDED[int(button.text)] = True

class MyApp(App):
    def build(self):
        return MyGrid()

if __name__ == '__main__':
    MyApp().run()

好吧,经过大量的试验和错误,我已经设法让这个东西工作了。不确定是什么修复了它,可能是缓冲区大小。所以我发现 "mic_callback" 实际上并没有被调用,因为队列中没有任何内容。所以问题应该出在音频输入的配置上。这对我有用(因为我很讨厌在这里发布我将使用 pastebin 的代码): http://pastebin.com/80sFjGWs

在 2021 年苦苦寻找这个问题答案的小伙伴们,不妨看看 kivy 的 plyer repository, especially to the one related with current question of audio recording