Skip to content

Instantly share code, notes, and snippets.

@tam17aki
Last active June 22, 2023 14:30
Show Gist options
  • Save tam17aki/8bfa2a42dab0061ee2641aed32dd1d30 to your computer and use it in GitHub Desktop.
Save tam17aki/8bfa2a42dab0061ee2641aed32dd1d30 to your computer and use it in GitHub Desktop.
Google Colab上で音声を録音するサンプル
Display the source blob
Display the rendered blob
Raw
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"name": "record_colab_sample.ipynb",
"provenance": [],
"collapsed_sections": []
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
},
"language_info": {
"name": "python"
}
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "UCI2UY3GaHjy"
},
"source": [
"# Google Colab上で音声を録音するサンプル"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "P0xRKObNadrP"
},
"source": [
"## 録音の関数を定義\n",
"\n",
"ESPnet2のサンプルスクリプトから借りました\n",
"\n",
"https://colab.research.google.com/github/espnet/notebook/blob/master/espnet2_asr_realtime_demo.ipynb"
]
},
{
"cell_type": "code",
"metadata": {
"id": "fACHVqYZaEPW"
},
"source": [
"from IPython.display import Javascript\n",
"from google.colab import output\n",
"from base64 import b64decode\n",
"\n",
"RECORD = \"\"\"\n",
"const sleep = time => new Promise(resolve => setTimeout(resolve, time))\n",
"const b2text = blob => new Promise(resolve => {\n",
" const reader = new FileReader()\n",
" reader.onloadend = e => resolve(e.srcElement.result)\n",
" reader.readAsDataURL(blob)\n",
"})\n",
"var record = time => new Promise(async resolve => {\n",
" stream = await navigator.mediaDevices.getUserMedia({ audio: true })\n",
" recorder = new MediaRecorder(stream)\n",
" chunks = []\n",
" recorder.ondataavailable = e => chunks.push(e.data)\n",
" recorder.start()\n",
" await sleep(time)\n",
" recorder.onstop = async ()=>{\n",
" blob = new Blob(chunks)\n",
" text = await b2text(blob)\n",
" resolve(text)\n",
" }\n",
" recorder.stop()\n",
"})\n",
"\"\"\"\n",
"\n",
"def record(sec, filename='audio.wav'):\n",
" display(Javascript(RECORD))\n",
" s = output.eval_js('record(%d)' % (sec * 1000))\n",
" b = b64decode(s.split(',')[1])\n",
" with open(filename, 'wb+') as f:\n",
" f.write(b)"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "suRXEjFCajEM"
},
"source": [
"## 録音の実行\n",
"\n",
"ファイル名、秒数は適当に決めています。\n",
"\n",
"ここでは、セルを実行すると3秒間マイクから音声を録音します。\n",
"\n",
"\"Speak to your microphone 3 sec...\"\n",
"\n",
"に続いて話してください。\n"
]
},
{
"cell_type": "code",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 51
},
"id": "NRr97NaVaMqk",
"outputId": "ce67b760-c91d-4bf4-a52e-6655bf8e38f8"
},
"source": [
"audiofile = \"audio.wav\"\n",
"second = 3\n",
"print(f\"Speak to your microphone {second} sec...\")\n",
"record(second, audiofile)\n",
"print(\"Done!\")"
],
"execution_count": null,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Speak to your microphone 3 sec...\n"
]
},
{
"output_type": "display_data",
"data": {
"application/javascript": [
"\n",
"const sleep = time => new Promise(resolve => setTimeout(resolve, time))\n",
"const b2text = blob => new Promise(resolve => {\n",
" const reader = new FileReader()\n",
" reader.onloadend = e => resolve(e.srcElement.result)\n",
" reader.readAsDataURL(blob)\n",
"})\n",
"var record = time => new Promise(async resolve => {\n",
" stream = await navigator.mediaDevices.getUserMedia({ audio: true })\n",
" recorder = new MediaRecorder(stream)\n",
" chunks = []\n",
" recorder.ondataavailable = e => chunks.push(e.data)\n",
" recorder.start()\n",
" await sleep(time)\n",
" recorder.onstop = async ()=>{\n",
" blob = new Blob(chunks)\n",
" text = await b2text(blob)\n",
" resolve(text)\n",
" }\n",
" recorder.stop()\n",
"})\n"
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {}
},
{
"output_type": "stream",
"name": "stdout",
"text": [
"Done!\n"
]
}
]
},
{
"cell_type": "code",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 330
},
"id": "Zhevn41icPvY",
"outputId": "e1e4c5f6-c184-4c3a-932b-827552931274"
},
"source": [
"# 波形プロットにより録音を確認\n",
"# UserWarning: PySoundFile failed. Trying audioread instead. が出るが、無視して問題ない\n",
"import librosa\n",
"import librosa.display\n",
"speech, rate = librosa.load(audiofile, sr=16000)\n",
"librosa.display.waveplot(speech, sr=rate)"
],
"execution_count": null,
"outputs": [
{
"output_type": "stream",
"name": "stderr",
"text": [
"/usr/local/lib/python3.7/dist-packages/librosa/core/audio.py:165: UserWarning: PySoundFile failed. Trying audioread instead.\n",
" warnings.warn(\"PySoundFile failed. Trying audioread instead.\")\n"
]
},
{
"output_type": "execute_result",
"data": {
"text/plain": [
"<matplotlib.collections.PolyCollection at 0x7f59600d5690>"
]
},
"metadata": {},
"execution_count": 3
},
{
"output_type": "display_data",
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
}
}
]
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment