1. 程式人生 > >處理音頻--pyaudio

處理音頻--pyaudio

header return tex 語音識別 tps res active script .post

    • 前言
    • 安裝
    • 讀寫音頻文件
      • play
      • record
      • wired
      • playcallback
      • Wirecallback
    • 外部應用
    • 總結

前言

很久之前寫過一個將文本轉成語音的,借助了一個名為pyttsx的庫。具體使用可以參考下面的鏈接。

http://blog.csdn.net/marksinoberg/article/details/52137547

今天再來分享一個處理音頻的博文。接住百度的語音接口,差不多可以方便的將音頻轉成文字了。

安裝

安裝的過程比較麻煩一點,不是說安裝的步驟,而是找到能用的庫不是很容易。

目標庫: pyaudio。

但是奈何我的Python版本是36,而pip是安裝不了的。找了很多資料,最後還是在pypi上找到了兼容的版本。

  • Python36版本: https://pypi.python.org/pypi/PyAudio/0.2.11

  • Python35 Python2:http://people.csail.mit.edu/hubert/pyaudio/packages/

讀寫音頻文件

官網上給了幾個小例子,個人覺得不錯。拿來分享一下。

play

"""PyAudio Example: Play a WAVE file."""

import pyaudio
import wave
import sys

CHUNK = 1024

if len(sys.argv) < 2:
    print("Plays a wave file.\n\nUsage: %s filename.wav"
% sys.argv[0]) sys.exit(-1) wf = wave.open(sys.argv[1], ‘rb‘) p = pyaudio.PyAudio() stream = p.open(format=p.get_format_from_width(wf.getsampwidth()), channels=wf.getnchannels(), rate=wf.getframerate(), output=True) data = wf.readframes(CHUNK) while
data != ‘‘: stream.write(data) data = wf.readframes(CHUNK) stream.stop_stream() stream.close() p.terminate()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

保存為play.py
然後可以再terminal中來嘗試一下。當然了,前提是先準備一個 .wav音頻文件。

Python play.py 3.12.wav
  • 1

然後不出意外的話,就可以聽到電腦播放的音頻了。

record

有了讀的,那麽再來個記錄的吧。

"""PyAudio example: Record a few seconds of audio and save to a WAVE file."""

import pyaudio
import wave

CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 44100
RECORD_SECONDS = 5
WAVE_OUTPUT_FILENAME = "output.wav"

p = pyaudio.PyAudio()

stream = p.open(format=FORMAT,
                channels=CHANNELS,
                rate=RATE,
                input=True,
                frames_per_buffer=CHUNK)

print("* recording")

frames = []

for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
    data = stream.read(CHUNK)
    frames.append(data)

print("* done recording")

stream.stop_stream()
stream.close()
p.terminate()

wf = wave.open(WAVE_OUTPUT_FILENAME, ‘wb‘)
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(b‘‘.join(frames))
wf.close()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

保存為record.py
然後運行下面的命令。

Python record.py
  • 1

代碼中聲明的是5秒的記錄時長,這一點可以根據自己的需要來進行動態的修改。然後程序運行結束之後,就會在同一級目錄下得到一個output.wav 的音頻文件。

wired

剛才那倆小例子要麽一個讀,要麽一個記錄。那麽要是既想讀,然後再看下結果的需求呢?可以這麽來實現。

"""
PyAudio Example: Make a wire between input and output (i.e., record a
few samples and play them back immediately).
"""

import pyaudio

CHUNK = 1024
WIDTH = 2
CHANNELS = 2
RATE = 44100
RECORD_SECONDS = 5

p = pyaudio.PyAudio()

stream = p.open(format=p.get_format_from_width(WIDTH),
                channels=CHANNELS,
                rate=RATE,
                input=True,
                output=True,
                frames_per_buffer=CHUNK)

print("* recording")

for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
    data = stream.read(CHUNK)
    stream.write(data, CHUNK)

print("* done")

stream.stop_stream()
stream.close()

p.terminate()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

保存為wire.py
然後運行下面的命令

Python wire.py
  • 1

就可以記錄一個5秒的實現了。

play(callback)

搞定了上面三個小例子,做出自己的東西也不是什麽難事了。基本上可以滿足自己的需求。但是官網上還給了更加優雅的方式,那就是使用回調函數。除此之外很重要的一點就是callback方式是noblocking的。
官網的api解釋如下:

Note that in “blocking mode”, each pyaudio.Stream.write() or pyaudio.Stream.read() blocks until all the given/requested frames have been played/recorded. Alternatively, to generate audio data on the fly or immediately process recorded audio data, use the “callback mode” outlined below.
  • 1
"""
PyAudio Example: Make a wire between input and output (i.e., record a
few samples and play them back immediately).
"""

import pyaudio

CHUNK = 1024
WIDTH = 2
CHANNELS = 2
RATE = 44100
RECORD_SECONDS = 5

p = pyaudio.PyAudio()

stream = p.open(format=p.get_format_from_width(WIDTH),
                channels=CHANNELS,
                rate=RATE,
                input=True,
                output=True,
                frames_per_buffer=CHUNK)

print("* recording")

for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
    data = stream.read(CHUNK)
    stream.write(data, CHUNK)

print("* done")

stream.stop_stream()
stream.close()

p.terminate()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

其實也沒啥特殊的地方了,就是代碼看起來更加精簡了。

Wire(callback)

"""
PyAudio Example: Make a wire between input and output (i.e., record a
few samples and play them back immediately).

This is the callback (non-blocking) version.
"""

import pyaudio
import time

WIDTH = 2
CHANNELS = 2
RATE = 44100

p = pyaudio.PyAudio()

def callback(in_data, frame_count, time_info, status):
    return (in_data, pyaudio.paContinue)

stream = p.open(format=p.get_format_from_width(WIDTH),
                channels=CHANNELS,
                rate=RATE,
                input=True,
                output=True,
                stream_callback=callback)

stream.start_stream()

while stream.is_active():
    time.sleep(0.1)

stream.stop_stream()
stream.close()

p.terminate()
License
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

外部應用

下面拿一個小例子入手,實時的測試一下音頻轉文字。因為本人沒有百度語音服務的權限,所以在網上搜索了一個key。在這裏感謝下面的這個鏈接。

https://github.com/luyishisi/python_yuyinduihua

話不多說, 上例子吧。

# coding: utf8

# @Author: 郭 璞
# @File: baiduyuyinshibie.py                                                                 
# @Time: 2017/5/10                                   
# @Contact: [email protected]
# @blog: http://blog.csdn.net/marksinoberg
# @Description: 百度語音識別接口調用
import wave
import requests
import json

def get_token():
    apiKey = "。。。GBOtpg22ZSGAU"
    secretKey = "44。。。e34936227d4a19dc2"

    auth_url = "https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id=" + apiKey + "&client_secret=" + secretKey
    response = requests.get(url=auth_url)
    jsondata = response.text
    return json.loads(jsondata)[‘access_token‘]

def use_cloud(token, wavefile):
    fp = wave.open(wavefile, ‘rb‘)
    # 已經錄好音的音頻片段內容
    nframes = fp.getnframes()
    filelength = nframes*2
    audiodata = fp.readframes(nframes)

    # 百度語音接口的產品ID
    cuid = ‘71XXXX663‘
    server_url = ‘http://vop.baidu.com/server_api‘ + ‘?cuid={}&token={}‘.format(cuid, token)
    headers = {
        ‘Content-Type‘: ‘audio/pcm; rete=8000‘,
        ‘Content-Length‘: ‘{}‘.format(filelength),
    }

    response = requests.post(url=server_url, headers=headers, data=audiodata)
    return response.text if response.status_code==200 else ‘Something Wrong!‘



if __name__ == ‘__main__‘:
    access_token = get_token()
    print(access_token)
    result = use_cloud(token=access_token, wavefile=‘./output.wav‘)
    print(result)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

音頻文件借助了上面第二個例子中錄制的音頻。

我說的話是: 345
# 由於在圖書館,所以不敢太大聲,要是用標準的普通話,相信準確度可能會更高一點。
  • 1
  • 2

然後運行的結果就是下面這樣的了。
技術分享圖片

可以看出請求成功,返回的結果裏面包含了相應的文本內容。雖然不是很準確,但是也還算可以吧。

總結

最後來總結一下,今天貌似凈拿人家的東西了,雖然自己整合了一下。但是還遠遠不夠啊。其實結合這個語音接口可以做出很多更加好玩的功能的。


參考鏈接:

聊天機器人

GitHub機器人聊天參考源碼

pyaudio官方文檔

pyaudio官網

PyPI寶庫

再分享一下我老師大神的人工智能教程吧。零基礎!通俗易懂!風趣幽默!還帶黃段子!希望你也加入到我們人工智能的隊伍中來!https://blog.csdn.net/jiangjunshow

處理音頻--pyaudio