diff --git a/.travis.yml b/.travis.yml index 64838155..58589541 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ python: env: - TOX_ENV=tan1uan5 - TOX_ENV=hap8sing5-tsi3giam7 -- TOX_ENV=hap8sing5-hun3lian7 +# - TOX_ENV=hap8sing5-hun3lian7 - TOX_ENV=huan1ik8 - TOX_ENV=flake8 addons: diff --git "a/\350\207\272\347\201\243\350\250\200\350\252\236\346\234\215\345\213\231/Kaldi\344\273\213\351\235\242.py" "b/\350\207\272\347\201\243\350\250\200\350\252\236\346\234\215\345\213\231/Kaldi\344\273\213\351\235\242.py" index 3cc78c8b..0a7709ce 100644 --- "a/\350\207\272\347\201\243\350\250\200\350\252\236\346\234\215\345\213\231/Kaldi\344\273\213\351\235\242.py" +++ "b/\350\207\272\347\201\243\350\250\200\350\252\236\346\234\215\345\213\231/Kaldi\344\273\213\351\235\242.py" @@ -1,5 +1,7 @@ from base64 import b64decode import json +from subprocess import Popen, PIPE +import wave from celery import shared_task from django.conf import settings @@ -7,6 +9,8 @@ HttpResponseBadRequest from django.utils.datastructures import MultiValueDictKeyError from django.views.decorators.csrf import csrf_exempt +from libavwrapper.avconv import Input, Output, AVConv +from libavwrapper.codec import AudioCodec, NO_VIDEO from 臺灣言語服務.Kaldi語料辨識 import Kaldi語料辨識 @@ -17,8 +21,23 @@ from 臺灣言語服務.KaldiModels import Kaldi辨識結果 +def Kaldi介面處理(參數無夠): + def 設定顯示資訊的函式(介面函式): + def 新函式(*陣列, **辭典): + try: + return 介面函式(*陣列, **辭典) + except MultiValueDictKeyError: + return HttpResponseBadRequest(參數無夠) + except EOFError: + return HttpResponseBadRequest( + '「blob」抑是「音檔」比RIFF檔頭閣較短!!' + ) + return 新函式 + return 設定顯示資訊的函式 + + @csrf_exempt -def 看辨識結果(request): +def 看辨識結果(_request): 結果 = [] for 辨識結果 in ( Kaldi辨識結果.objects @@ -52,66 +71,26 @@ def 看辨識結果(request): @csrf_exempt +@Kaldi介面處理(參數無夠='設定「語言」參數以外,閣愛傳「blob」抑是「音檔」!!') def Kaldi辨識(request): try: 啥人唸的 = request.POST['啥人唸的'].strip() except MultiValueDictKeyError: 啥人唸的 = '無註明' - try: - Kaldi辨識 = Kaldi語料辨識.匯入音檔(request.POST['語言'], 啥人唸的, 揣音檔出來(request), '') - except MultiValueDictKeyError: - return HttpResponseBadRequest( - '設定「語言」參數以外,閣愛傳「blob」抑是「音檔」!!' - ) + Kaldi辨識 = Kaldi語料辨識.匯入音檔( + request.POST['語言'], 啥人唸的, 音檔參數.揣音檔出來(request), '' + ) Kaldi辨識影音.delay(Kaldi辨識.id) return HttpResponse('上傳成功!!') -def 揣音檔出來(request): - try: - return 聲音檔.對資料轉(request.FILES['音檔'].read()) - except MultiValueDictKeyError: - pass - return 聲音檔.對資料轉(blob2bytes(request.POST['blob'])) - - -def blob2bytes(blob): - return bytes(json.loads( - '[' + b64decode(blob).decode('utf-8') + ']' - )) - - -def 無辨識過的重訓練一擺(): - for Kaldi辨識 in Kaldi語料辨識.objects.filter(辨識好猶未=False): - Kaldi辨識.辨識() - return JsonResponse({'成功': '成功'}) - - @shared_task def Kaldi辨識影音(Kaldi辨識編號): Kaldi語料辨識.objects.get(pk=Kaldi辨識編號).辨識() @csrf_exempt -def Kaldi對齊(request): - try: - 語言 = request.POST['語言'] - 文本 = request.POST['文本'] - 語料對齊 = Kaldi語料對齊.匯入音檔( - 語言, '無註明', - 揣音檔出來(request), - 文本.replace('\r\n', '\n').replace('\r', '\n') - ) - except MultiValueDictKeyError: - return HttpResponseBadRequest( - '設定「語言」參數以外,閣愛傳「文本」佮「blob」抑是「音檔」!!' - ) - Kaldi對齊影音.delay(語料對齊.pk) - return HttpResponse('上傳成功!!') - - -@csrf_exempt -def 看對齊結果(request): +def 看對齊結果(_request): 結果 = [] for 對齊結果 in ( Kaldi對齊結果.objects @@ -137,6 +116,58 @@ def 看對齊結果(request): return JsonResponse({'對齊結果': 結果}) +@csrf_exempt +@Kaldi介面處理(參數無夠='設定「語言」參數以外,閣愛傳「文本」佮「blob」抑是「音檔」!!') +def Kaldi對齊(request): + 語言 = request.POST['語言'] + 文本 = request.POST['文本'] + 語料對齊 = Kaldi語料對齊.匯入音檔( + 語言, '無註明', + 音檔參數.揣音檔出來(request), + 文本.replace('\r\n', '\n').replace('\r', '\n') + ) + Kaldi對齊影音.delay(語料對齊.pk) + return HttpResponse('上傳成功!!') + + @shared_task def Kaldi對齊影音(對齊編號): Kaldi語料對齊.objects.get(pk=對齊編號).對齊() + + +class 音檔參數: + @classmethod + def 揣音檔出來(cls, request): + 音檔字串 = cls._揣音檔字串出來(request) + try: + return 聲音檔.對資料轉(音檔字串) + except wave.Error: + return 聲音檔.對資料轉(cls._轉做wav檔(音檔字串)) + + @classmethod + def _揣音檔字串出來(cls, request): + try: + return request.FILES['音檔'].read() + except MultiValueDictKeyError: + pass + return cls._blob2bytes(request.POST['blob']) + + @classmethod + def _轉做wav檔(cls, 音檔字串): + wav聲音格式 = AudioCodec('pcm_s16le') + 輸入 = Input('pipe:') + 輸出 = Output('pipe:') + 指令 = AVConv( + 'avconv', ('-loglevel', 'panic'), + 輸入, + ('-f', 'wav'), wav聲音格式, NO_VIDEO, 輸出 + ) + 程序 = Popen(list(指令), stdin=PIPE, stdout=PIPE,) + 結果, _錯誤 = 程序.communicate(input=音檔字串) + return 結果 + + @classmethod + def _blob2bytes(cls, blob): + return bytes(json.loads( + '[' + b64decode(blob).decode('utf-8') + ']' + )) diff --git "a/\350\207\272\347\201\243\350\250\200\350\252\236\346\234\215\345\213\231/management/commands/Kaldi\350\276\250\350\255\230\344\270\200\346\226\227.py" "b/\350\207\272\347\201\243\350\250\200\350\252\236\346\234\215\345\213\231/management/commands/Kaldi\350\276\250\350\255\230\344\270\200\346\226\227.py" index dbde12d3..ce5ed5d5 100644 --- "a/\350\207\272\347\201\243\350\250\200\350\252\236\346\234\215\345\213\231/management/commands/Kaldi\350\276\250\350\255\230\344\270\200\346\226\227.py" +++ "b/\350\207\272\347\201\243\350\250\200\350\252\236\346\234\215\345\213\231/management/commands/Kaldi\350\276\250\350\255\230\344\270\200\346\226\227.py" @@ -1,11 +1,12 @@ from django.core.management.base import BaseCommand -from 臺灣言語服務.Kaldi介面 import 無辨識過的重訓練一擺 +from 臺灣言語服務.Kaldi語料辨識 import Kaldi語料辨識 class Command(BaseCommand): help = '無辨識過的音檔重訓練一擺' - def handle(self, *args, **參數): - 無辨識過的重訓練一擺() + def handle(self, *_args, **_參數): + for Kaldi辨識 in Kaldi語料辨識.objects.filter(辨識好猶未=False): + Kaldi辨識.辨識() diff --git "a/\350\251\246\351\251\227/Kaldi/\350\276\250\350\255\230/imtong/sui2.mp3" "b/\350\251\246\351\251\227/Kaldi/\350\276\250\350\255\230/imtong/sui2.mp3" new file mode 100644 index 00000000..31fb0527 Binary files /dev/null and "b/\350\251\246\351\251\227/Kaldi/\350\276\250\350\255\230/imtong/sui2.mp3" differ diff --git "a/\350\251\246\351\251\227/Kaldi/\350\276\250\350\255\230/test\350\276\250\350\255\230\344\273\213\351\235\242\345\226\256\345\205\203\350\251\246\351\251\227.py" "b/\350\251\246\351\251\227/Kaldi/\350\276\250\350\255\230/test\350\276\250\350\255\230\344\273\213\351\235\242\345\226\256\345\205\203\350\251\246\351\251\227.py" index 6e93cd76..9b3192e2 100644 --- "a/\350\251\246\351\251\227/Kaldi/\350\276\250\350\255\230/test\350\276\250\350\255\230\344\273\213\351\235\242\345\226\256\345\205\203\350\251\246\351\251\227.py" +++ "b/\350\251\246\351\251\227/Kaldi/\350\276\250\350\255\230/test\350\276\250\350\255\230\344\273\213\351\235\242\345\226\256\345\205\203\350\251\246\351\251\227.py" @@ -1,6 +1,7 @@ from base64 import b64encode import io import json +from os.path import abspath, dirname, join from django.test.testcases import TestCase from django.urls.base import resolve @@ -50,6 +51,25 @@ def test_file有音檔(self): self.音檔.wav格式資料() ) + def test_短檔毋是wav(self): + with io.BytesIO(b'sui2') as 音檔: + 回應 = self.client.post('/辨識音檔', { + '語言': '台語', + '音檔': 音檔, + }) + self.assertEqual(回應.status_code, 400) + + def test_長檔mp3(self): + with open( + join(dirname(abspath(__file__)), 'imtong', 'sui2.mp3'), 'rb' + ) as mp3_tong: + with io.BytesIO(mp3_tong.read()) as 音檔: + self.client.post('/辨識音檔', { + '語言': '台語', + '音檔': 音檔, + }) + Kaldi辨識結果.objects.get().聲音檔().wav格式資料() + def test_音檔佮blob攏無傳(self): 回應 = self.client.post('/辨識音檔', { '語言': '台語',