forked from tykayn/transcription
Compare commits
27 Commits
Author | SHA1 | Date | |
---|---|---|---|
89374d2418 | |||
f5d4a76db9 | |||
fe4129a4ee | |||
27765e243d | |||
4ce54d002c | |||
0b79f0799d | |||
0160050928 | |||
|
fd2c3bab33 | ||
|
4ed0bcb786 | ||
096400fbf2 | |||
ccc48c09d7 | |||
|
27b82d9d0d | ||
|
b618dfe7c3 | ||
|
c0f2f4d225 | ||
ed4d03342d | |||
8d31bff32a | |||
590fcfd6ff | |||
|
e784cec6ab | ||
|
9cbc47ea19 | ||
|
32cb91f07d | ||
|
42fede81e5 | ||
29c19f6906 | |||
2bc3b295b8 | |||
fa3b6bc744 | |||
|
6fd015290c | ||
|
9f46ed3960 | ||
db9f74b519 |
11
.gitignore
vendored
Normal file → Executable file
11
.gitignore
vendored
Normal file → Executable file
@ -1,7 +1,18 @@
|
||||
/models/fr/*
|
||||
/models/en/*
|
||||
!/input/demo.wav
|
||||
/input/*.ogg
|
||||
/input/*.mp4
|
||||
/input/*.mkv
|
||||
/input/*.flac
|
||||
/input/*.mp3
|
||||
/input/converted_to_wav/*.wav
|
||||
/input/already_converted/*
|
||||
/output/**/*.txt
|
||||
/output/**/*.csv
|
||||
/output/**/*.json
|
||||
/output/**/*.srt
|
||||
.idea
|
||||
input/ydl/*
|
||||
input/fait/*
|
||||
/vosk-model*
|
||||
|
8
.idea/.gitignore
vendored
8
.idea/.gitignore
vendored
@ -1,8 +0,0 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/transcription-vosk.iml" filepath="$PROJECT_DIR$/.idea/transcription-vosk.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
@ -1,11 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/models" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/input/converted_to_wav" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
0
LICENSE.md
Normal file → Executable file
0
LICENSE.md
Normal file → Executable file
4
Makefile
Normal file → Executable file
4
Makefile
Normal file → Executable file
@ -1,7 +1,11 @@
|
||||
default: install
|
||||
install:
|
||||
bash install.sh
|
||||
wav:
|
||||
bash inputs_to_wav.sh
|
||||
convert:
|
||||
bash transcript.sh $(args)
|
||||
convert_en:
|
||||
bash english_transcript.sh $(args)
|
||||
srt:
|
||||
perl clean.sh $(args) > output/clean.srt
|
||||
|
47
README.md
Normal file → Executable file
47
README.md
Normal file → Executable file
@ -2,33 +2,41 @@
|
||||
|
||||
configuration pour transcrire des fichiers audio wav avec Vosk
|
||||
|
||||
## mode d'emploi
|
||||
## Mode d'emploi
|
||||
|
||||
### installation
|
||||
#### Prérequis
|
||||
* python3 (pour l'école serpentard)
|
||||
* pip (gestionnaire de paquets python)
|
||||
* pip3 version 19 (gestionnaire de paquets python)
|
||||
* git (gestion de version)
|
||||
* unzip (décompression de modèle)
|
||||
* jq (pour le nettoyage de fichier json)
|
||||
* ffmpeg (pour la conversion vers wav)
|
||||
* youtube-dl si vous souhaitez utiliser le website
|
||||
* 4Go de ram, 2Go serait trop juste pour utiliser le modèle fr par défaut.
|
||||
* testé sur Ubuntu 20.04
|
||||
|
||||
pour les installer avec aptitude
|
||||
```
|
||||
sudo apt install jq python3-pip git ffmpeg
|
||||
```
|
||||
|
||||
#### cloner ce dépot dans un dossier de travail
|
||||
#### Cloner ce dépot dans un dossier de travail
|
||||
```bash
|
||||
git clone https://forge.chapril.org/tykayn/transcription.git && cd transcription
|
||||
```
|
||||
|
||||
* installer vosk via le MakeFile, vérifiez les prérequis ci-dessus. une fois dans votre dossier de transcription fraîchement cloné, faites la commande:
|
||||
```
|
||||
```bash
|
||||
make
|
||||
```
|
||||
* mettre un fichier audio dans le dossier "input"
|
||||
* le convertir en wav mono (avec audacity par exemple)
|
||||
* lancer la transcription du wav mono. Une démo est disponible, extraite de l'émission Libre à vous!
|
||||
* le convertir en wav mono
|
||||
```bash
|
||||
make wav
|
||||
```
|
||||
* lancer la transcription du wav mono. Une démo est disponible, extraite de l'émission Libre à vous!
|
||||
```bash
|
||||
make convert file=input/demo.wav
|
||||
```
|
||||
n'oubliez pas l'argument `file=`
|
||||
@ -43,10 +51,35 @@ Chaque fichier transcrit a un sous-dossier de son nom dans le dossier output. Ai
|
||||
* si deux personnes parlent rapidement l'une après l'autre, vosk considèrera qu'il s'agit d'une seule phrase.
|
||||
* les transcriptions peuvent être faites pour plusieurs langues, il faudra modifier le fichier "conversion_simple_fr.py" si on veut autre chose que du Français.
|
||||
|
||||
# évolutions possibles
|
||||
# Évolutions possibles
|
||||
- convertir un fichier mp3 vers WAV mono avec ffmpeg.
|
||||
- nettoyer l'écho et normaliser le fichier audio.
|
||||
- permettre le traitement en masse de plusieurs fichiers de podcast et leur donner un output nommé comme le fichier d'entrée afin de les distinguer.
|
||||
# Modèles de voix
|
||||
Common voice: 22Go
|
||||
https://commonvoice.mozilla.org/fr/datasets
|
||||
|
||||
Other models
|
||||
Other places where you can check for models which might be compatible:
|
||||
|
||||
https://kaldi-asr.org/models.html - variety of models from Kaldi - librispeech, aspire, chinese models
|
||||
https://github.com/daanzu/kaldi-active-grammar/blob/master/docs/models.md - Big dictation models for English
|
||||
https://github.com/uhh-lt/vosk-model-tuda-de - German models
|
||||
https://github.com/german-asr/kaldi-german - Another German project
|
||||
https://zamia-speech.org/asr/ - German and English model from Zamia
|
||||
https://github.com/pguyot/zamia-speech/releases - French models for Zamia
|
||||
https://github.com/opensource-spraakherkenning-nl/Kaldi_NL - Dutch model
|
||||
https://montreal-forced-aligner.readthedocs.io/en/latest/pretrained_models.html (GMM models, not compatible but might be still useful)
|
||||
https://github.com/goodatlas/zeroth - Korean Kaldi (just a recipe and data to train)
|
||||
https://github.com/undertheseanlp/automatic_speech_recognition - Vietnamese Kaldi project
|
||||
https://doc.linto.ai/#/services/linstt - LINTO project with French and English models
|
||||
https://community.rhasspy.org/ - Rhasspy (some Kaldi models for Czech, probably even more)
|
||||
https://github.com/feddybear/flipside_ph - Filipino model project by Federico Ang
|
||||
https://github.com/alumae/kiirkirjutaja - Estonian Speech Recognition project with Vosk models
|
||||
https://github.com/falabrasil/kaldi-br - Portuguese models from FalaBrasil project
|
||||
https://github.com/egorsmkv/speech-recognition-uk - Ukrainian ASR project with Vosk models
|
||||
https://github.com/Appen/UHV-OTS-Speech - repository from Appen for Scalable Data Annotation Pipeline for High-Quality Large Speech Datasets Development
|
||||
https://github.com/vistec-AI/commonvoice-th - Thai models trained on CommonVoice
|
||||
|
||||
# liens
|
||||
* [podcast libre à vous](https://cause-commune.fm/podcastfilter/libre-a-vous/)
|
||||
|
74
base_transcript.sh
Normal file
74
base_transcript.sh
Normal file
@ -0,0 +1,74 @@
|
||||
#!/bin/bash
|
||||
# utilisation: bash transcript.sh MONFICHIER.wav
|
||||
# auteur du script: tykayn contact@cipherbliss.com
|
||||
file="input/already_converted/demo.wav"
|
||||
echo "########### $(date) : conversion de fichier audio .WAV mono piste uniquement,
|
||||
avec Vosk installé par pip3, et un modèle de textes en français."
|
||||
echo " "
|
||||
echo "########### $(date) : fichier : $file"
|
||||
|
||||
FOLDER_MODEL="fr"
|
||||
|
||||
# existence du modèle demandé
|
||||
if [ -d "models/$FOLDER_MODEL" ]; then
|
||||
echo "models/$FOLDER_MODEL le modèle est bien présent."
|
||||
else
|
||||
pwd
|
||||
ls -l models
|
||||
echo " "
|
||||
echo "########### $(date) : [ERREUR] le modèle de données dans models/$FOLDER_MODEL n'existe pas, vérifiez son installation :C peut être avez vous oublié de faire une commande 'make'"
|
||||
|
||||
exit 1
|
||||
fi
|
||||
# existence du fichier demandé
|
||||
if [ -f "$file" ]; then
|
||||
echo "$file exists."
|
||||
else
|
||||
echo "########### $(date) : [ERREUR] voici les fichiers disponibles dans input/converted_to_wav: "
|
||||
ls -l input/converted_to_wav
|
||||
echo "########### $(date) : [ERREUR] le fichier $file n'existe PAS :C "
|
||||
exit 1
|
||||
fi
|
||||
echo " "
|
||||
FILE_NAME=$(basename $file .wav)
|
||||
OUT_DIR=$( echo "output/$FILE_NAME")
|
||||
mkdir output/$FILE_NAME
|
||||
|
||||
python3 ./extract_srt.py "$file" > $OUT_DIR/0_output.json
|
||||
|
||||
|
||||
|
||||
echo " "
|
||||
echo "########### $(date) : nettoyer la sortie "
|
||||
jq .text $OUT_DIR/0_output.json > $OUT_DIR/1_converted.txt
|
||||
jq .text $OUT_DIR/0_output_$FILE_NAME.json > $OUT_DIR/1_converted_$FILE_NAME.txt
|
||||
|
||||
sed 's/null//g' $OUT_DIR/1_converted.txt > $OUT_DIR/2_without_nulls.txt
|
||||
sed 's/^ *//; s/ *$//; /^$/d' $OUT_DIR/2_without_nulls.txt > $OUT_DIR/3_without_nulls.txt
|
||||
sed 's/\"//g' $OUT_DIR/3_without_nulls.txt > $OUT_DIR/4_phrases.txt
|
||||
sed 's/null//g' $OUT_DIR/1_converted_$FILE_NAME.txt > $OUT_DIR/2_without_nulls_$FILE_NAME.txt
|
||||
sed 's/^ *//; s/ *$//; /^$/d' $OUT_DIR/2_without_nulls_$FILE_NAME.txt > $OUT_DIR/3_without_nulls_$FILE_NAME.txt
|
||||
sed 's/\"//g' $OUT_DIR/3_without_nulls_$FILE_NAME.txt > $OUT_DIR/4_phrases_$FILE_NAME.txt
|
||||
echo "########### $(date) : OK "
|
||||
echo " "
|
||||
COUNT_LINES=$(cat $OUT_DIR/phrases.txt |wc -l)
|
||||
cat $OUT_DIR/4_phrases.txt
|
||||
COUNT_LINES=$(cat $OUT_DIR/phrases_$FILE_NAME.txt |wc -l)
|
||||
cat $OUT_DIR/4_phrases_$FILE_NAME.txt
|
||||
echo " "
|
||||
echo "########### $(date) : lignes transcriptes $COUNT_LINES "
|
||||
echo "########### $(date) : conversion faite dans output/converted_out_without_nulls.txt"
|
||||
echo "########### $(date) : conversion de la sortie en pseudo fichier de sous titres"
|
||||
perl clean.sh $OUT_DIR/0_output.json > $OUT_DIR/5_phrases_min_sec.txt
|
||||
perl clean.sh $OUT_DIR/0_output_$FILE_NAME.json > $OUT_DIR/5_phrases_min_sec_$FILE_NAME.txt
|
||||
cat $OUT_DIR/5_phrases_min_sec.srt
|
||||
|
||||
echo "########### $(date) : conversion de la sortie en fichier de sous titres "
|
||||
python3 ./extract_srt.py "$file" > $OUT_DIR/5_output.srt
|
||||
python3 ./extract_srt.py "$file" > $OUT_DIR/5_output_$FILE_NAME.srt
|
||||
|
||||
ls -l $OUT_DIR
|
||||
|
||||
echo "########### $(date) : conversion faite "
|
||||
exit 0
|
||||
|
30
conversion_simple_en.py
Executable file
30
conversion_simple_en.py
Executable file
@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from vosk import Model, KaldiRecognizer, SetLogLevel
|
||||
import sys
|
||||
import os
|
||||
import wave
|
||||
|
||||
SetLogLevel(0)
|
||||
|
||||
if not os.path.exists("models/en"):
|
||||
print ("Please download the model from https://alphacephei.com/vosk/models and unpack as 'models' in the current folder.")
|
||||
exit (1)
|
||||
|
||||
|
||||
wf = wave.open(sys.argv[1], "rb")
|
||||
if wf.getnchannels() != 1 or wf.getsampwidth() != 2 or wf.getcomptype() != "NONE":
|
||||
print ("Audio file must be WAV format mono PCM.")
|
||||
exit (1)
|
||||
|
||||
model = Model("models/en")
|
||||
rec = KaldiRecognizer(model, wf.getframerate())
|
||||
|
||||
while True:
|
||||
data = wf.readframes(4000)
|
||||
if len(data) == 0:
|
||||
break
|
||||
if rec.AcceptWaveform(data):
|
||||
print(rec.Result())
|
||||
|
||||
print(rec.FinalResult())
|
23
conversion_simple_fr.py
Normal file → Executable file
23
conversion_simple_fr.py
Normal file → Executable file
@ -1,22 +1,29 @@
|
||||
#!/usr/bin/env python3
|
||||
#!/usr/bin/python3
|
||||
|
||||
from vosk import Model, KaldiRecognizer, SetLogLevel
|
||||
import sys
|
||||
import os
|
||||
import wave
|
||||
|
||||
SetLogLevel(0)
|
||||
modelDir=os.path.dirname(sys.argv[0])+"/models/fr"
|
||||
|
||||
if not os.path.exists("models/fr"):
|
||||
print ("Please download the model from https://alphacephei.com/vosk/models and unpack as 'models' in the current folder.")
|
||||
SetLogLevel(0)
|
||||
if not os.path.exists(modelDir):
|
||||
print ("Please download the model from https://alphacephei.com/vosk/models and unpack as '{}'.".format(modelDir))
|
||||
exit (1)
|
||||
|
||||
|
||||
wf = wave.open(sys.argv[1], "rb")
|
||||
if wf.getnchannels() != 1 or wf.getsampwidth() != 2 or wf.getcomptype() != "NONE":
|
||||
print ("Audio file must be WAV format mono PCM.")
|
||||
framerate=wf.getframerate()
|
||||
nchannels=wf.getnchannels()
|
||||
sampwidth=wf.getsampwidth()
|
||||
comptype=wf.getcomptype()
|
||||
if framerate < 16000 or nchannels != 1 or sampwidth != 2 or comptype != "NONE":
|
||||
print ("Audio file has : {} Hz sample rate, {} channels, {} byte sample width and {} compression type".format(framerate, nchannels, sampwidth, comptype))
|
||||
print ("when 16000 Hz sample rate, 1 channel, 2 byte sample width and NONE compression type are required")
|
||||
exit (1)
|
||||
|
||||
model = Model("models/fr")
|
||||
model = Model(modelDir)
|
||||
rec = KaldiRecognizer(model, wf.getframerate())
|
||||
|
||||
while True:
|
||||
@ -25,7 +32,5 @@ while True:
|
||||
break
|
||||
if rec.AcceptWaveform(data):
|
||||
print(rec.Result())
|
||||
#else:
|
||||
# print(rec.PartialResult())
|
||||
|
||||
print(rec.FinalResult())
|
||||
|
74
en_test_base_transcript.sh
Normal file
74
en_test_base_transcript.sh
Normal file
@ -0,0 +1,74 @@
|
||||
#!/bin/bash
|
||||
# utilisation: bash transcript.sh MONFICHIER.wav
|
||||
# auteur du script: tykayn contact@cipherbliss.com
|
||||
file="input/already_converted/audio_drive_thru.wav"
|
||||
echo "########### $(date) : conversion de fichier audio .WAV mono piste uniquement,
|
||||
avec Vosk installé par pip3, et un modèle de textes en français."
|
||||
echo " "
|
||||
echo "########### $(date) : fichier : $file"
|
||||
|
||||
FOLDER_MODEL="en"
|
||||
|
||||
# existence du modèle demandé
|
||||
if [ -d "models/$FOLDER_MODEL" ]; then
|
||||
echo "models/$FOLDER_MODEL le modèle est bien présent."
|
||||
else
|
||||
pwd
|
||||
ls -l models
|
||||
echo " "
|
||||
echo "########### $(date) : [ERREUR] le modèle de données dans models/$FOLDER_MODEL n'existe pas, vérifiez son installation :C peut être avez vous oublié de faire une commande 'make'"
|
||||
|
||||
exit 1
|
||||
fi
|
||||
# existence du fichier demandé
|
||||
if [ -f "$file" ]; then
|
||||
echo "$file exists."
|
||||
else
|
||||
echo "########### $(date) : [ERREUR] voici les fichiers disponibles dans input/converted_to_wav: "
|
||||
ls -l input/converted_to_wav
|
||||
echo "########### $(date) : [ERREUR] le fichier $file n'existe PAS :C "
|
||||
exit 1
|
||||
fi
|
||||
echo " "
|
||||
FILE_NAME=$(basename $file .wav)
|
||||
OUT_DIR=$( echo "output/$FILE_NAME")
|
||||
mkdir -p output/$FILE_NAME
|
||||
|
||||
python3 ./extract_srt_en.py "$file" > $OUT_DIR/0_output.json
|
||||
|
||||
|
||||
|
||||
echo " "
|
||||
echo "########### $(date) : nettoyer la sortie "
|
||||
jq .text $OUT_DIR/0_output.json > $OUT_DIR/1_converted.txt
|
||||
jq .text $OUT_DIR/0_output_$FILE_NAME.json > $OUT_DIR/1_converted_$FILE_NAME.txt
|
||||
|
||||
sed 's/null//g' $OUT_DIR/1_converted.txt > $OUT_DIR/2_without_nulls.txt
|
||||
sed 's/^ *//; s/ *$//; /^$/d' $OUT_DIR/2_without_nulls.txt > $OUT_DIR/3_without_nulls.txt
|
||||
sed 's/\"//g' $OUT_DIR/3_without_nulls.txt > $OUT_DIR/4_phrases.txt
|
||||
sed 's/null//g' $OUT_DIR/1_converted_$FILE_NAME.txt > $OUT_DIR/2_without_nulls_$FILE_NAME.txt
|
||||
sed 's/^ *//; s/ *$//; /^$/d' $OUT_DIR/2_without_nulls_$FILE_NAME.txt > $OUT_DIR/3_without_nulls_$FILE_NAME.txt
|
||||
sed 's/\"//g' $OUT_DIR/3_without_nulls_$FILE_NAME.txt > $OUT_DIR/4_phrases_$FILE_NAME.txt
|
||||
echo "########### $(date) : OK "
|
||||
echo " "
|
||||
COUNT_LINES=$(cat $OUT_DIR/phrases.txt |wc -l)
|
||||
cat $OUT_DIR/4_phrases.txt
|
||||
COUNT_LINES=$(cat $OUT_DIR/phrases_$FILE_NAME.txt |wc -l)
|
||||
cat $OUT_DIR/4_phrases_$FILE_NAME.txt
|
||||
echo " "
|
||||
echo "########### $(date) : lignes transcriptes $COUNT_LINES "
|
||||
echo "########### $(date) : conversion faite dans output/converted_out_without_nulls.txt"
|
||||
echo "########### $(date) : conversion de la sortie en pseudo fichier de sous titres"
|
||||
perl clean.sh $OUT_DIR/0_output.json > $OUT_DIR/5_phrases_min_sec.txt
|
||||
perl clean.sh $OUT_DIR/0_output_$FILE_NAME.json > $OUT_DIR/5_phrases_min_sec_$FILE_NAME.txt
|
||||
cat $OUT_DIR/5_phrases_min_sec.srt
|
||||
|
||||
echo "########### $(date) : conversion de la sortie en fichier de sous titres "
|
||||
python3 ./extract_srt.py "$file" > $OUT_DIR/5_output.srt
|
||||
python3 ./extract_srt.py "$file" > $OUT_DIR/5_output_$FILE_NAME.srt
|
||||
|
||||
ls -l $OUT_DIR
|
||||
|
||||
echo "########### $(date) : conversion faite "
|
||||
exit 0
|
||||
|
121
english_transcript.sh
Executable file
121
english_transcript.sh
Executable file
@ -0,0 +1,121 @@
|
||||
#!/bin/bash
|
||||
# utilisation: bash transcript.sh MONFICHIER.wav
|
||||
# auteur du script: tykayn contact@cipherbliss.com
|
||||
# ```bash
|
||||
# bash transcript.sh myfile fr 1
|
||||
# ```
|
||||
echo " Transcript of a file - [file relative path \"input/aside/demo.wav\"] [lang en or fr] [enable srt conversion 1 or 0]"
|
||||
# ----------------- Default parameters -----------------
|
||||
#ENABLE_SRT=false
|
||||
ENABLE_SRT=true
|
||||
# disponibles: "fr" ou "en", trouvez d'autres modèles prédéfinis https://alphacephei.com/vosk/models
|
||||
#FOLDER_MODEL="fr"
|
||||
FOLDER_MODEL="en"
|
||||
DEFAULT_FILE_TO_TRANSCRIPT="input/aside/demo.wav"
|
||||
STARTTIME=$(date +%s)
|
||||
|
||||
# ----------------- prise en compte des arguments rentrés par l'utilisateur
|
||||
echo "=====> langue: $FOLDER_MODEL"
|
||||
echo "=====> fichier à convertir: $1"
|
||||
|
||||
if [ $1 ]; then
|
||||
file=$1
|
||||
|
||||
|
||||
else
|
||||
echo "utilisation du fichier de démo"
|
||||
file=$DEFAULT_FILE_TO_TRANSCRIPT
|
||||
fi
|
||||
if [ $2 ]; then
|
||||
lang_to_search=$2
|
||||
else
|
||||
lang_to_search=$FOLDER_MODEL
|
||||
fi
|
||||
if [ $3 ]; then
|
||||
ENABLE_SRT=$3
|
||||
else
|
||||
ENABLE_SRT=$ENABLE_SRT
|
||||
fi
|
||||
|
||||
echo " [file name]: $file, [lang]: $lang_to_search, [enable srt conversion]: $ENABLE_SRT."
|
||||
|
||||
FILE_NAME=$(basename $file .wav)
|
||||
|
||||
output_dir="output"
|
||||
if [ $2 ]; then
|
||||
output_dir=$2
|
||||
fi
|
||||
OUT_DIR=$( echo "$output_dir/$FILE_NAME")
|
||||
|
||||
echo "########### $(date) : conversion de fichier audio .WAV mono piste uniquement,
|
||||
avec Vosk installé par pip3, et un modèle de textes en Anglais."
|
||||
echo " "
|
||||
echo "########### $(date) : fichier : $file : $1"
|
||||
|
||||
|
||||
# ----------------- recherche de l'existence du modèle de langue demandé -----------------
|
||||
if [ -d "models/$lang_to_search" ]; then
|
||||
echo "models/$lang_to_search le modèle est bien présent."
|
||||
else
|
||||
pwd
|
||||
ls -l models
|
||||
echo " "
|
||||
echo "########### $(date) : [ERREUR] le modèle de données dans models/$lang_to_search n'existe pas, vérifiez son installation :C peut être avez vous oublié de faire une commande 'make'"
|
||||
|
||||
exit 1
|
||||
fi
|
||||
# ----------------- existence du fichier demandé -----------------
|
||||
if [ -f "$file" ]; then
|
||||
echo "$file exists."
|
||||
else
|
||||
echo "########### $(date) : [ERREUR] fichier introuvable: $file"
|
||||
echo "########### $(date) : [ERREUR] voici les fichiers disponibles dans input/converted_to_wav: "
|
||||
echo " "
|
||||
ls -l input/converted_to_wav
|
||||
echo " "
|
||||
echo "########### $(date) : [ERREUR] le fichier $file n'existe PAS :C "
|
||||
exit 1
|
||||
fi
|
||||
echo " "
|
||||
|
||||
mkdir output/$FILE_NAME -p
|
||||
echo " convertir en sous titre ? $ENABLE_SRT"
|
||||
if ($ENABLE_SRT) ; then
|
||||
echo "########### $(date) : conversion de $file ,sortie en fichier de sous titres .srt"
|
||||
echo ""
|
||||
echo "## (cela prend plusieurs minutes généralement 1 / 10ème du temps du fichier audio)"
|
||||
echo "..."
|
||||
python3 ./extract_srt.py "$file" > $OUT_DIR/6_output_$FILE_NAME.srt
|
||||
cat $OUT_DIR/6_output_$FILE_NAME.srt
|
||||
COUNT_LINES=$(cat $OUT_DIR/6_output_$FILE_NAME.srt |wc -l)
|
||||
echo " "
|
||||
echo "-------------- DONE ------------"
|
||||
echo " $COUNT_LINES lines in $OUT_DIR/6_phrases_min_sec.srt"
|
||||
else
|
||||
echo "########### $(date) : conversion de la sortie en divers fichiers marquant les temps et sans marquage"
|
||||
python3 ./conversion_simple_en.py "$file" > $OUT_DIR/0_output_$FILE_NAME.json
|
||||
|
||||
echo " "
|
||||
echo "########### $(date) : nettoyer la sortie "
|
||||
jq .text $OUT_DIR/0_output_$FILE_NAME.json > $OUT_DIR/1_converted_$FILE_NAME.txt
|
||||
|
||||
sed 's/null//g' $OUT_DIR/1_converted_$FILE_NAME.txt > $OUT_DIR/2_without_nulls_$FILE_NAME.txt
|
||||
sed 's/^ *//; s/ *$//; /^$/d' $OUT_DIR/2_without_nulls_$FILE_NAME.txt > $OUT_DIR/3_without_nulls_$FILE_NAME.txt
|
||||
sed 's/\"//g' $OUT_DIR/3_without_nulls_$FILE_NAME.txt > $OUT_DIR/4_phrases_$FILE_NAME.txt
|
||||
echo "########### $(date) : OK "
|
||||
echo " "
|
||||
COUNT_LINES=$(cat $OUT_DIR/4_phrases_$FILE_NAME.txt |wc -l)
|
||||
cat $OUT_DIR/4_phrases_$FILE_NAME.txt
|
||||
echo " $COUNT_LINES lines in $OUT_DIR/4_phrases_$FILE_NAME.txt"
|
||||
echo " "
|
||||
echo "########### $(date) : lignes transcriptes $COUNT_LINES "
|
||||
echo "########### $(date) : conversion faite dans output/converted_out_without_nulls.txt"
|
||||
echo "########### $(date) : conversion de la sortie en pseudo fichier de sous titres"
|
||||
perl clean.sh $OUT_DIR/0_output_$FILE_NAME.json > $OUT_DIR/5_phrases_min_sec_$FILE_NAME.txt
|
||||
|
||||
|
||||
fi
|
||||
|
||||
echo "########### $(date) : conversion faite "
|
||||
echo "########### en $SECONDS seconds"
|
||||
exit 0
|
17
extract_srt.py
Normal file → Executable file
17
extract_srt.py
Normal file → Executable file
@ -1,5 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
# TODO tqdm
|
||||
# prend un fichier audio et imprime des sous titres au format srt
|
||||
|
||||
from vosk import Model, KaldiRecognizer, SetLogLevel
|
||||
import sys
|
||||
import os
|
||||
@ -8,12 +9,16 @@ import json
|
||||
import argparse
|
||||
from collections import namedtuple
|
||||
from pprint import pprint
|
||||
import time
|
||||
try:
|
||||
from tqdm import tqdm
|
||||
tqdm_installed = True
|
||||
except:
|
||||
tqdm_installed = False
|
||||
|
||||
start_time = time.time()
|
||||
MODEL_LANG="fr"
|
||||
|
||||
class SubPart:
|
||||
|
||||
def __init__(self, start, end, text):
|
||||
@ -37,7 +42,7 @@ class SubPart:
|
||||
"""[1:-1]
|
||||
|
||||
|
||||
def gen_subparts(input_file, model_dir, verbose=False, partlen=4, progress=False):
|
||||
def gen_subparts(input_file, model_dir, verbose=False, partlen=4, progress=True):
|
||||
SetLogLevel(0 if verbose else -1)
|
||||
|
||||
model = Model(model_dir)
|
||||
@ -92,7 +97,7 @@ def gen_subparts(input_file, model_dir, verbose=False, partlen=4, progress=False
|
||||
else:
|
||||
pass
|
||||
#print(rec.PartialResult())
|
||||
#pprint(rec.PartialResult())
|
||||
# pprint(rec.PartialResult())
|
||||
if progress:
|
||||
pbar.close()
|
||||
r = json.loads(rec.PartialResult())
|
||||
@ -115,16 +120,16 @@ def create_parser():
|
||||
def main():
|
||||
args = create_parser().parse_args()
|
||||
if tqdm_installed:
|
||||
it = enumerate(gen_subparts(args.input, "models/fr", args.verbose, args.interval, args.progress))
|
||||
it = enumerate(gen_subparts(args.input, "models/"+MODEL_LANG, args.verbose, args.interval, args.progress))
|
||||
else:
|
||||
it = enumerate(gen_subparts(args.input, "models/fr", args.verbose, args.interval, False))
|
||||
it = enumerate(gen_subparts(args.input, "models/"+MODEL_LANG, args.verbose, args.interval, False))
|
||||
for i,subpart in it:
|
||||
n = i+1
|
||||
args.output.write(f"""{n}
|
||||
{subpart}
|
||||
|
||||
"""
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
132
extract_srt_en.py
Executable file
132
extract_srt_en.py
Executable file
@ -0,0 +1,132 @@
|
||||
#!/usr/bin/env python3
|
||||
# TODO tqdm
|
||||
from vosk import Model, KaldiRecognizer, SetLogLevel
|
||||
import sys
|
||||
import os
|
||||
import subprocess
|
||||
import json
|
||||
import argparse
|
||||
from collections import namedtuple
|
||||
from pprint import pprint
|
||||
try:
|
||||
from tqdm import tqdm
|
||||
tqdm_installed = True
|
||||
except:
|
||||
tqdm_installed = False
|
||||
|
||||
class SubPart:
|
||||
|
||||
def __init__(self, start, end, text):
|
||||
self.start = start
|
||||
self.end = end
|
||||
self.text = text
|
||||
|
||||
@staticmethod
|
||||
def ftot(f):
|
||||
h = int(f//3600)
|
||||
m = int(f//60 % 60)
|
||||
s = int(f//1 % 60)
|
||||
ms = int((1000 * f) % 1000)
|
||||
s = f"{h:02}:{m:02}:{s:02},{ms:03}"
|
||||
return s
|
||||
|
||||
def __repr__(self):
|
||||
return f"""
|
||||
{self.ftot(self.start)} --> {self.ftot(self.end)}
|
||||
{self.text}
|
||||
"""[1:-1]
|
||||
|
||||
|
||||
def gen_subparts(input_file, model_dir, verbose=False, partlen=4, progress=False):
|
||||
SetLogLevel(0 if verbose else -1)
|
||||
|
||||
model = Model(model_dir)
|
||||
rec = KaldiRecognizer(model, 16000)
|
||||
|
||||
process = subprocess.Popen(['ffmpeg', '-loglevel', 'quiet', '-i',
|
||||
input_file,
|
||||
'-ar', str(16000) , '-ac', '1', '-f', 's16le', '-'],
|
||||
stdout=subprocess.PIPE)
|
||||
|
||||
r = subprocess.run("ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1".split() + [input_file], stdout=subprocess.PIPE)
|
||||
duration = float(r.stdout.decode('utf-8').strip())
|
||||
|
||||
if progress:
|
||||
pbar = tqdm(total=duration, unit="s")
|
||||
|
||||
prev_end = 0
|
||||
while True:
|
||||
data = process.stdout.read(4000)
|
||||
if len(data) == 0:
|
||||
break
|
||||
if rec.AcceptWaveform(data):
|
||||
r = json.loads(rec.Result())
|
||||
if 'result' in r:
|
||||
resultpart = [] # TODO: use this across AccesptForm
|
||||
for result in r['result']:
|
||||
if len(resultpart) > 0 and float(result['end']) - float(resultpart[0]['start']) >= partlen:
|
||||
yield SubPart(start=resultpart[0]['start'],
|
||||
end=float(resultpart[-1]['end']),
|
||||
text=" ".join(r['word'] for r in resultpart))
|
||||
prev_end = float(resultpart[-1]['end'])
|
||||
resultpart = []
|
||||
if float(result['end'] - result['start']) >= partlen:
|
||||
yield SubPart(start=float(result['start']),
|
||||
end=float(result['end']),
|
||||
text=result['word'])
|
||||
prev_end = float(result['end'])
|
||||
resultpart = []
|
||||
else:
|
||||
resultpart.append(result)
|
||||
if progress:
|
||||
pbar.update(float(result['end'] - pbar.n))
|
||||
|
||||
|
||||
if len(resultpart) > 0:
|
||||
yield SubPart(start=float(resultpart[0]['start']),
|
||||
end=float(resultpart[-1]['end']),
|
||||
text=" ".join(r['word'] for r in resultpart))
|
||||
prev_end = float(resultpart[-1]['end'])
|
||||
resultpart = []
|
||||
|
||||
else:
|
||||
pass
|
||||
#print(rec.PartialResult())
|
||||
#pprint(rec.PartialResult())
|
||||
if progress:
|
||||
pbar.close()
|
||||
r = json.loads(rec.PartialResult())
|
||||
text = r['partial']
|
||||
yield SubPart(start=prev_end, end=duration, text=text)
|
||||
|
||||
|
||||
def create_parser():
|
||||
parser = argparse.ArgumentParser(prog="SRT file extractor using Speech-To-Text")
|
||||
parser.add_argument("-v", "--verbose", action="store_true")
|
||||
parser.add_argument("-o", "--output", type=argparse.FileType('w+'), default=sys.stdout)
|
||||
parser.add_argument("-m", "--model", required=False)
|
||||
parser.add_argument("-i", "--interval", default=4)
|
||||
if tqdm_installed:
|
||||
parser.add_argument("-p", "--progress", action="store_true")
|
||||
parser.add_argument("input")
|
||||
return parser
|
||||
|
||||
|
||||
def main():
|
||||
args = create_parser().parse_args()
|
||||
if tqdm_installed:
|
||||
it = enumerate(gen_subparts(args.input, "models/en", args.verbose, args.interval, args.progress))
|
||||
else:
|
||||
it = enumerate(gen_subparts(args.input, "models/en", args.verbose, args.interval, False))
|
||||
for i,subpart in it:
|
||||
n = i+1
|
||||
args.output.write(f"""{n}
|
||||
{subpart}
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
0
input/.gitkeep
Normal file → Executable file
0
input/.gitkeep
Normal file → Executable file
0
input/demo.wav → input/aside/demo.wav
Normal file → Executable file
0
input/demo.wav → input/aside/demo.wav
Normal file → Executable file
0
input/converted_to_wav/.gitkeep
Normal file → Executable file
0
input/converted_to_wav/.gitkeep
Normal file → Executable file
89
inputs_to_wav.sh
Executable file
89
inputs_to_wav.sh
Executable file
@ -0,0 +1,89 @@
|
||||
#!/bin/bash
|
||||
# utilisation: bash inputs_to_wav.sh
|
||||
# auteur du script: tykayn contact@cipherbliss.com
|
||||
|
||||
echo "########### conversion des fichiers audio (mkv, mp3, mp4, ogg, webm, wav, avi) placés dans le dossier input, vers du wav mono-piste uniquement dans le dossier input/converted_to_wav"
|
||||
echo " "
|
||||
|
||||
cd input
|
||||
|
||||
if -f already_converted; then
|
||||
mkdir already_converted
|
||||
fi
|
||||
|
||||
for i in *.avi; do
|
||||
echo "fichier à traiter: $i"
|
||||
ffmpeg -i "$i" -ac 1 "converted_to_wav/${i%avi}wav"
|
||||
|
||||
echo " converti en WAV, déplacement dans le dossier input/already_converted"
|
||||
mv "$i" already_converted/
|
||||
done
|
||||
|
||||
|
||||
for i in *.flac; do
|
||||
echo "fichier à traiter: $i"
|
||||
ffmpeg -i "$i" -ac 1 "converted_to_wav/${i%flac}wav"
|
||||
|
||||
echo " converti en WAV, déplacement dans le dossier input/already_converted"
|
||||
mv "$i" already_converted/
|
||||
done
|
||||
|
||||
for i in *.mkv; do
|
||||
|
||||
echo "fichier à traiter: $i"
|
||||
ffmpeg -i "$i" -ac 1 "converted_to_wav/${i%mkv}wav"
|
||||
|
||||
echo " converti en WAv, déplacement dans le dossier input/already_converted"
|
||||
mv "$i" already_converted/
|
||||
done
|
||||
|
||||
for i in *.mp3; do
|
||||
|
||||
echo "fichier à traiter: $i"
|
||||
ffmpeg -i "$i" -ac 1 "converted_to_wav/${i%mp3}wav"
|
||||
|
||||
echo " converti en WAv, déplacement dans le dossier input/already_converted"
|
||||
mv "$i" already_converted/
|
||||
done
|
||||
|
||||
for i in *.mp4; do
|
||||
|
||||
echo "fichier à traiter: $i"
|
||||
ffmpeg -i "$i" -ac 1 "converted_to_wav/${i%mp4}wav"
|
||||
|
||||
echo " converti en WAv, déplacement dans le dossier input/already_converted"
|
||||
mv "$i" already_converted/
|
||||
done
|
||||
|
||||
for i in *.ogg; do
|
||||
|
||||
echo "fichier à traiter: $i"
|
||||
ffmpeg -i "$i" -ac 1 "converted_to_wav/${i%ogg}wav"
|
||||
|
||||
echo " converti en WAv, déplacement dans le dossier input/already_converted"
|
||||
mv "$i" already_converted/
|
||||
done
|
||||
|
||||
for i in *.webm; do
|
||||
|
||||
echo "fichier à traiter: $i"
|
||||
ffmpeg -i "$i" -ac 1 "converted_to_wav/${i%webm}wav"
|
||||
|
||||
echo " converti en WAv, déplacement dans le dossier input/already_converted"
|
||||
mv "$i" already_converted/
|
||||
done
|
||||
|
||||
for i in *.wav; do
|
||||
|
||||
echo "fichier à traiter: $i"
|
||||
ffmpeg -i "$i" -ac 1 "converted_to_wav/${i%wav}wav"
|
||||
|
||||
echo " converti en WAv, déplacement dans le dossier input/already_converted"
|
||||
mv "$i" already_converted/
|
||||
done
|
||||
|
||||
|
||||
COUNT_LINES=$(ls -l input/converted_to_wav | wc -l)
|
||||
echo "########### fichiers wav dans le dossier input/converted_to_wav: $COUNT_LINES "
|
||||
echo "########### conversion faite dans output/converted_out_without_nulls.txt"
|
||||
exit 0
|
24
install.sh
Normal file → Executable file
24
install.sh
Normal file → Executable file
@ -29,13 +29,32 @@ echo " "
|
||||
mkdir -p models/fr
|
||||
echo -e "${green}########### Procéder au téléchargement du modèle Français (1.6go) pour transcrire les textes ?${reset} (écrivez o pour oui et faites entrée pour valider) ${reset}"
|
||||
read proceed
|
||||
|
||||
# les autres modèles sont ici https://alphacephei.com/vosk/models
|
||||
if [[ $proceed == o* ]]; then
|
||||
echo "C'est parti."
|
||||
if [ ! -f "vosk-model-fr-0.6-linto-2.2.0.zip" ]; then
|
||||
echo "Récupération du modèle en Français vosk-model-fr-0.6-linto-2.2.0.zip"
|
||||
wget https://alphacephei.com/vosk/models/vosk-model-fr-0.6-linto-2.2.0.zip
|
||||
echo -e "${green}########### téléchargement du modèle OK ${reset}"
|
||||
unzip vosk-model-fr-0.6-linto-2.2.0.zip -d models/fr
|
||||
echo -e "${green}########### décompression du modèle OK ${reset}"
|
||||
unzip vosk-model-fr-0.6-linto-2.2.0.zip
|
||||
mv vosk-model-fr-0.6-linto-2.2.0 models/fr
|
||||
echo -e "${green}########### décompression du modèle en Français OK ${reset}"
|
||||
ls -l models/fr
|
||||
else
|
||||
echo "fichier zip vosk-model-fr-0.6-linto-2.2.0.zip déjà présent"
|
||||
fi
|
||||
if [ ! -f "vosk-model-en-us-0.42-gigaspeech.zip" ]; then
|
||||
echo "Récupération du modèle en Anglais vosk-model-fr-0.6-linto-2.2.0.zip"
|
||||
wget https://alphacephei.com/vosk/models/vosk-model-en-us-0.42-gigaspeech.zip
|
||||
echo -e "${green}########### téléchargement du modèle OK ${reset}"
|
||||
unzip vosk-model-en-us-0.42-gigaspeech.zip
|
||||
mv vosk-model-en-us-0.42-gigaspeech.zip models/en
|
||||
echo -e "${green}########### décompression du modèle en Français OK ${reset}"
|
||||
ls -l models/en
|
||||
else
|
||||
echo "fichier zip vosk-model-fr-0.6-linto-2.2.0.zip déjà présent"
|
||||
fi
|
||||
else
|
||||
echo -e "${green}########### vous n'avez pas souhaité télécharger le modèle ${reset}"
|
||||
echo -e "${green}########### fin de l'installation sans télécharger de modèle de langue ${reset}"
|
||||
@ -45,3 +64,4 @@ fi
|
||||
|
||||
|
||||
echo -e "${green}########### installation ok ${reset}"
|
||||
exit 0
|
44
log_ydl.txt
Executable file
44
log_ydl.txt
Executable file
@ -0,0 +1,44 @@
|
||||
total 1708
|
||||
-rw-r--r-- 1 www-data www-data 271266 Mar 23 09:48 base.mp3
|
||||
-rw-r--r-- 1 www-data www-data 1470542 Mar 27 14:43 mono_canal.wav
|
||||
Sat Mar 27 14:43:32 CET 2021 ###### end conversion __ 2021-Mar-27_1616852609 __ https://peertube.cipherbliss.com/videos/watch/e6a37508-042e-4d83-8598-5d36b764bb3d
|
||||
total 1708
|
||||
-rw-r--r-- 1 www-data www-data 271266 Mar 23 09:48 base.mp3
|
||||
-rw-r--r-- 1 www-data www-data 1470542 Mar 27 21:48 mono_canal.wav
|
||||
Sat Mar 27 21:48:48 CET 2021 ###### end conversion __ 2021-Mar-27_1616878123 __ https://peertube.cipherbliss.com/videos/watch/e6a37508-042e-4d83-8598-5d36b764bb3d
|
||||
total 1708
|
||||
-rw-r--r-- 1 www-data www-data 271266 Mar 23 09:48 base.mp3
|
||||
-rw-r--r-- 1 www-data www-data 1470542 Apr 20 17:19 mono_canal.wav
|
||||
Tue Apr 20 17:19:20 CEST 2021 ###### end conversion __ 2021-Apr-20_1618931951 __ https://peertube.cipherbliss.com/videos/watch/e6a37508-042e-4d83-8598-5d36b764bb3d
|
||||
total 1708
|
||||
-rw-r--r-- 1 www-data www-data 271266 Mar 23 09:48 base.mp3
|
||||
-rw-r--r-- 1 www-data www-data 1470542 Apr 20 17:37 mono_canal.wav
|
||||
Tue Apr 20 17:37:31 CEST 2021 ###### end conversion __ 2021-Apr-20_1618933048 __ https://peertube.cipherbliss.com/videos/watch/e6a37508-042e-4d83-8598-5d36b764bb3d
|
||||
total 1708
|
||||
-rw-r--r-- 1 www-data www-data 271266 Mar 23 09:48 base.mp3
|
||||
-rw-r--r-- 1 www-data www-data 1470542 Aug 18 16:09 mono_canal.wav
|
||||
Wed Aug 18 16:09:53 CEST 2021 ###### end conversion __ 2021-Aug-18_1629295789 __ https://peertube.cipherbliss.com/videos/watch/e6a37508-042e-4d83-8598-5d36b764bb3d
|
||||
total 1708
|
||||
-rw-r--r-- 1 www-data www-data 271266 Mar 23 09:48 base.mp3
|
||||
-rw-r--r-- 1 www-data www-data 1470542 Aug 18 16:10 mono_canal.wav
|
||||
Wed Aug 18 16:10:50 CEST 2021 ###### end conversion __ 2021-Aug-18_1629295848 __ https://peertube.cipherbliss.com/videos/watch/e6a37508-042e-4d83-8598-5d36b764bb3d
|
||||
total 1708
|
||||
-rw-r--r-- 1 www-data www-data 271266 Mar 23 09:48 base.mp3
|
||||
-rw-r--r-- 1 www-data www-data 1470542 Aug 18 16:12 mono_canal.wav
|
||||
Wed Aug 18 16:12:13 CEST 2021 ###### end conversion __ 2021-Aug-18_1629295930 __ https://peertube.cipherbliss.com/videos/watch/e6a37508-042e-4d83-8598-5d36b764bb3d
|
||||
total 1708
|
||||
-rw-r--r-- 1 www-data www-data 271266 Mar 23 09:48 base.mp3
|
||||
-rw-r--r-- 1 www-data www-data 1470542 Aug 18 16:14 mono_canal.wav
|
||||
Wed Aug 18 16:14:15 CEST 2021 ###### end conversion __ demo_video_tk __ https://peertube.cipherbliss.com/videos/watch/e6a37508-042e-4d83-8598-5d36b764bb3d
|
||||
total 1708
|
||||
-rw-r--r-- 1 www-data www-data 271266 Mar 23 09:48 base.mp3
|
||||
-rw-r--r-- 1 www-data www-data 1470542 Aug 18 16:14 mono_canal.wav
|
||||
Wed Aug 18 16:15:56 CEST 2021 ###### end conversion __ demo_video_tk __ https://peertube.cipherbliss.com/videos/watch/e6a37508-042e-4d83-8598-5d36b764bb3d
|
||||
total 1708
|
||||
-rw-r--r-- 1 www-data www-data 271266 Mar 23 09:48 base.mp3
|
||||
-rw-r--r-- 1 www-data www-data 1470542 Aug 18 16:14 mono_canal.wav
|
||||
Wed Aug 18 16:16:17 CEST 2021 ###### end conversion __ demo_video_tk __ https://peertube.cipherbliss.com/videos/watch/e6a37508-042e-4d83-8598-5d36b764bb3d
|
||||
total 1708
|
||||
-rw-r--r-- 1 www-data www-data 271266 Mar 23 09:48 base.mp3
|
||||
-rw-r--r-- 1 www-data www-data 1470542 Aug 18 16:14 mono_canal.wav
|
||||
Wed Aug 18 16:17:22 CEST 2021 ###### end conversion __ demo_video_tk __ https://peertube.cipherbliss.com/videos/watch/e6a37508-042e-4d83-8598-5d36b764bb3d
|
80
microphone.py
Normal file
80
microphone.py
Normal file
@ -0,0 +1,80 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
import queue
|
||||
import sys
|
||||
import sounddevice as sd
|
||||
|
||||
from vosk import Model, KaldiRecognizer
|
||||
|
||||
q = queue.Queue()
|
||||
|
||||
def int_or_str(text):
|
||||
"""Helper function for argument parsing."""
|
||||
try:
|
||||
return int(text)
|
||||
except ValueError:
|
||||
return text
|
||||
|
||||
def callback(indata, frames, time, status):
|
||||
"""This is called (from a separate thread) for each audio block."""
|
||||
if status:
|
||||
print(status, file=sys.stderr)
|
||||
q.put(bytes(indata))
|
||||
|
||||
parser = argparse.ArgumentParser(add_help=False)
|
||||
parser.add_argument(
|
||||
"-l", "--list-devices", action="store_true",
|
||||
help="show list of audio devices and exit")
|
||||
args, remaining = parser.parse_known_args()
|
||||
if args.list_devices:
|
||||
print(sd.query_devices())
|
||||
parser.exit(0)
|
||||
parser = argparse.ArgumentParser(
|
||||
description=__doc__,
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
parents=[parser])
|
||||
parser.add_argument(
|
||||
"-f", "--filename", type=str, metavar="FILENAME",
|
||||
help="audio file to store recording to")
|
||||
parser.add_argument(
|
||||
"-d", "--device", type=int_or_str,
|
||||
help="input device (numeric ID or substring)")
|
||||
parser.add_argument(
|
||||
"-r", "--samplerate", type=int, help="sampling rate")
|
||||
args = parser.parse_args(remaining)
|
||||
|
||||
try:
|
||||
if args.samplerate is None:
|
||||
device_info = sd.query_devices(args.device, "input")
|
||||
# soundfile expects an int, sounddevice provides a float:
|
||||
args.samplerate = int(device_info["default_samplerate"])
|
||||
|
||||
model = Model("models/fr")
|
||||
|
||||
if args.filename:
|
||||
dump_fn = open(args.filename, "wb")
|
||||
else:
|
||||
dump_fn = None
|
||||
|
||||
with sd.RawInputStream(samplerate=args.samplerate, blocksize = 8000, device=args.device,
|
||||
dtype="int16", channels=1, callback=callback):
|
||||
print("#" * 80)
|
||||
print("Press Ctrl+C to stop the recording")
|
||||
print("#" * 80)
|
||||
|
||||
rec = KaldiRecognizer(model, args.samplerate)
|
||||
while True:
|
||||
data = q.get()
|
||||
if rec.AcceptWaveform(data):
|
||||
print(rec.Result())
|
||||
# else:
|
||||
# print(rec.PartialResult())
|
||||
if dump_fn is not None:
|
||||
dump_fn.write(data)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("\nDone")
|
||||
parser.exit(0)
|
||||
except Exception as e:
|
||||
parser.exit(type(e).__name__ + ": " + str(e))
|
0
models/.gitkeep
Normal file → Executable file
0
models/.gitkeep
Normal file → Executable file
@ -1,20 +0,0 @@
|
||||
#!/bin/bash
|
||||
# utilisation: bash transcript.sh MONFICHIER.wav
|
||||
# auteur du script: tykayn contact@cipherbliss.com
|
||||
|
||||
echo "########### conversion des fichiers audio .ogg placés dans le dossier input, vers du wav mono-piste uniquement"
|
||||
echo " "
|
||||
for i in input/*.mp3; do
|
||||
ffmpeg -acodec libvorbis -i "$i" -acodec pcm_s16le "input/converted_to_wav/${i%mp3}wav"
|
||||
done
|
||||
|
||||
echo " "
|
||||
echo "########### OK "
|
||||
echo " "
|
||||
COUNT_LINES_OGG=$(ll input/*.ogg |wc -l)
|
||||
COUNT_LINES=$(ll input/converted_to_wav |wc -l)
|
||||
|
||||
echo "########### fichiers ogg dans le dossier input: $COUNT_LINES_OGG "
|
||||
echo "########### fichiers wav dans le dossier input: $COUNT_LINES "
|
||||
echo "########### conversion faite dans output/converted_out_without_nulls.txt"
|
||||
exit 0
|
@ -1,21 +0,0 @@
|
||||
#!/bin/bash
|
||||
# utilisation: bash transcript.sh MONFICHIER.wav
|
||||
# auteur du script: tykayn contact@cipherbliss.com
|
||||
|
||||
echo "########### conversion des fichiers audio .ogg dans le dossier input, vers du wav mono-piste uniquement,
|
||||
avec Vosk installé par pip3, et un modèle de textes en français."
|
||||
echo " "
|
||||
for i in input/*.ogg; do
|
||||
ffmpeg -acodec libvorbis -i "$i" -acodec pcm_s16le "input/converted_to_wav/${i%ogg}wav"
|
||||
done
|
||||
|
||||
echo " "
|
||||
echo "########### OK "
|
||||
echo " "
|
||||
COUNT_LINES_OGG=$(ll input/*.ogg |wc -l)
|
||||
COUNT_LINES=$(ll input/converted_to_wav |wc -l)
|
||||
|
||||
echo "########### fichiers ogg dans le dossier input: $COUNT_LINES_OGG "
|
||||
echo "########### fichiers wav dans le dossier input: $COUNT_LINES "
|
||||
echo "########### conversion faite dans output/converted_out_without_nulls.txt"
|
||||
exit 0
|
0
output/.gitkeep
Normal file → Executable file
0
output/.gitkeep
Normal file → Executable file
76
setup.py
Normal file
76
setup.py
Normal file
@ -0,0 +1,76 @@
|
||||
import os
|
||||
import setuptools
|
||||
import shutil
|
||||
import glob
|
||||
import platform
|
||||
|
||||
# Figure out environment for cross-compile
|
||||
vosk_source = os.getenv("VOSK_SOURCE", os.path.abspath(os.path.join(os.path.dirname(__file__),
|
||||
"..")))
|
||||
system = os.environ.get('VOSK_PLATFORM', platform.system())
|
||||
architecture = os.environ.get('VOSK_ARCHITECTURE', platform.architecture()[0])
|
||||
|
||||
# Copy precompmilled libraries
|
||||
for lib in glob.glob(os.path.join(vosk_source, "src/lib*.*")):
|
||||
print ("Adding library", lib)
|
||||
shutil.copy(lib, "vosk")
|
||||
|
||||
# Create OS-dependent, but Python-independent wheels.
|
||||
try:
|
||||
from wheel.bdist_wheel import bdist_wheel
|
||||
except ImportError:
|
||||
cmdclass = {}
|
||||
else:
|
||||
class bdist_wheel_tag_name(bdist_wheel):
|
||||
def get_tag(self):
|
||||
abi = 'none'
|
||||
if system == 'Darwin':
|
||||
oses = 'macosx_10_6_universal2'
|
||||
elif system == 'Windows' and architecture == '32bit':
|
||||
oses = 'win32'
|
||||
elif system == 'Windows' and architecture == '64bit':
|
||||
oses = 'win_amd64'
|
||||
elif system == 'Linux' and architecture == '64bit':
|
||||
oses = 'linux_x86_64'
|
||||
elif system == 'Linux' and architecture == 'aarch64':
|
||||
oses = 'manylinux2014_aarch64'
|
||||
elif system == 'Linux':
|
||||
oses = 'linux_' + architecture
|
||||
else:
|
||||
raise TypeError("Unknown build environment")
|
||||
return 'py3', abi, oses
|
||||
cmdclass = {'bdist_wheel': bdist_wheel_tag_name}
|
||||
|
||||
with open("README.md", "rb") as fh:
|
||||
long_description = fh.read().decode("utf-8")
|
||||
|
||||
setuptools.setup(
|
||||
name="vosk",
|
||||
version="0.3.43",
|
||||
author="Alpha Cephei Inc",
|
||||
author_email="contact@alphacephei.com",
|
||||
description="Offline open source speech recognition API based on Kaldi and Vosk",
|
||||
long_description=long_description,
|
||||
long_description_content_type="text/markdown",
|
||||
url="https://github.com/alphacep/vosk-api",
|
||||
packages=setuptools.find_packages(),
|
||||
package_data = {'vosk': ['*.so', '*.dll', '*.dyld']},
|
||||
entry_points = {
|
||||
'console_scripts': ['vosk-transcriber=vosk.transcriber.cli:main'],
|
||||
},
|
||||
include_package_data=True,
|
||||
classifiers=[
|
||||
'Programming Language :: Python :: 3',
|
||||
'License :: OSI Approved :: Apache Software License',
|
||||
'Operating System :: Microsoft :: Windows',
|
||||
'Operating System :: POSIX :: Linux',
|
||||
'Operating System :: MacOS :: MacOS X',
|
||||
'Topic :: Software Development :: Libraries :: Python Modules'
|
||||
],
|
||||
cmdclass=cmdclass,
|
||||
python_requires='>=3',
|
||||
zip_safe=False, # Since we load so file from the filesystem, we can not run from zip file
|
||||
setup_requires=['cffi>=1.0', 'requests', 'tqdm', 'srt', 'websockets'],
|
||||
install_requires=['cffi>=1.0', 'requests', 'tqdm', 'srt', 'websockets'],
|
||||
cffi_modules=['vosk_builder.py:ffibuilder'],
|
||||
)
|
58
transcribe_2.py
Normal file
58
transcribe_2.py
Normal file
@ -0,0 +1,58 @@
|
||||
from vosk import Model, KaldiRecognizer, SetLogLevel
|
||||
from tqdm.notebook import tqdm
|
||||
import wave
|
||||
import os
|
||||
import json
|
||||
|
||||
def transcript_file(input_file, model_path):
|
||||
|
||||
# Check if file exists
|
||||
if not os.path.isfile(input_file):
|
||||
raise FileNotFoundError(os.path.basename(input_file) + " not found")
|
||||
|
||||
# Check if model path exists
|
||||
if not os.path.exists(model_path):
|
||||
raise FileNotFoundError(os.path.basename(model_path) + " not found")
|
||||
|
||||
# open audio file
|
||||
wf = wave.open(input_file, "rb")
|
||||
|
||||
# check if wave file has the right properties
|
||||
if wf.getnchannels() != 1 or wf.getsampwidth() != 2 or wf.getcomptype() != "NONE":
|
||||
raise TypeError("Audio file must be WAV format mono PCM.")
|
||||
|
||||
# Initialize model
|
||||
model = Model(model_path)
|
||||
rec = KaldiRecognizer(model, wf.getframerate())
|
||||
|
||||
# Get file size (to calculate progress bar)
|
||||
file_size = os.path.getsize(input_file)
|
||||
|
||||
# Run transcription
|
||||
pbar = tqdm(total=file_size)
|
||||
|
||||
# To store our results
|
||||
transcription = []
|
||||
|
||||
while True:
|
||||
data = wf.readframes(4000) # use buffer of 4000
|
||||
pbar.update(len(data))
|
||||
if len(data) == 0:
|
||||
pbar.set_description("Transcription finished")
|
||||
break
|
||||
if rec.AcceptWaveform(data):
|
||||
# Convert json output to dict
|
||||
result_dict = json.loads(rec.Result())
|
||||
# Extract text values and append them to transcription list
|
||||
transcription.append(result_dict.get("text", ""))
|
||||
|
||||
# Get final bits of audio and flush the pipeline
|
||||
final_result = json.loads(rec.FinalResult())
|
||||
transcription.append(final_result.get("text", ""))
|
||||
|
||||
transcription_text = ' '.join(transcription)
|
||||
|
||||
return transcription_text
|
||||
|
||||
wave_file = '/input/already_converted/drive_thu.wav'
|
||||
transcription = transcript_file(wave_file, 'models/en')
|
136
transcript.sh
Normal file → Executable file
136
transcript.sh
Normal file → Executable file
@ -1,42 +1,120 @@
|
||||
#!/bin/bash
|
||||
# utilisation: bash transcript.sh MONFICHIER.wav
|
||||
# auteur du script: tykayn contact@cipherbliss.com
|
||||
# ```bash
|
||||
# bash transcript.sh myfile fr 1
|
||||
# ```
|
||||
echo " Transcript of a file - [file relative path \"input/aside/demo.wav\"] [lang en or fr] [enable srt conversion 1 or 0]"
|
||||
# ----------------- Default parameters -----------------
|
||||
#ENABLE_SRT=false
|
||||
ENABLE_SRT=true
|
||||
# disponibles: "fr" ou "en", trouvez d'autres modèles prédéfinis https://alphacephei.com/vosk/models
|
||||
FOLDER_MODEL="fr"
|
||||
#FOLDER_MODEL="en"
|
||||
DEFAULT_FILE_TO_TRANSCRIPT="input/aside/demo.wav"
|
||||
STARTTIME=$(date +%s)
|
||||
|
||||
# ----------------- prise en compte des arguments rentrés par l'utilisateur
|
||||
echo "=====> langue: $FOLDER_MODEL"
|
||||
echo "=====> fichier à convertir: $1"
|
||||
|
||||
if [ $1 ]; then
|
||||
file=$1
|
||||
else
|
||||
echo "utilisation du fichier de démo"
|
||||
file=$DEFAULT_FILE_TO_TRANSCRIPT
|
||||
fi
|
||||
if [ $2 ]; then
|
||||
lang_to_search=$2
|
||||
else
|
||||
lang_to_search=$FOLDER_MODEL
|
||||
fi
|
||||
if [ $3 ]; then
|
||||
ENABLE_SRT=$3
|
||||
else
|
||||
ENABLE_SRT=$ENABLE_SRT
|
||||
fi
|
||||
|
||||
echo " [file name]: $file, [lang]: $lang_to_search, [enable srt conversion]: $ENABLE_SRT."
|
||||
|
||||
FILE_NAME=$(basename $file .wav)
|
||||
|
||||
output_dir="output"
|
||||
if [ $2 ]; then
|
||||
output_dir=$2
|
||||
fi
|
||||
OUT_DIR=$( echo "$output_dir/$FILE_NAME")
|
||||
|
||||
echo "########### $(date) : conversion de fichier audio .WAV mono piste uniquement,
|
||||
avec Vosk installé par pip3, et un modèle de textes en français."
|
||||
echo " "
|
||||
echo "########### $(date) : fichier : $file"
|
||||
echo "########### $(date) : fichier : $file : $1"
|
||||
|
||||
|
||||
# ----------------- recherche de l'existence du modèle de langue demandé -----------------
|
||||
if [ -d "models/$lang_to_search" ]; then
|
||||
echo "models/$lang_to_search le modèle est bien présent."
|
||||
else
|
||||
pwd
|
||||
ls -l models
|
||||
echo " "
|
||||
echo "########### $(date) : [ERREUR] le modèle de données dans models/$lang_to_search n'existe pas, vérifiez son installation :C peut être avez vous oublié de faire une commande 'make'"
|
||||
|
||||
exit 1
|
||||
fi
|
||||
# ----------------- existence du fichier demandé -----------------
|
||||
if [ -f "$file" ]; then
|
||||
echo "$file exists."
|
||||
else
|
||||
echo "########### $(date) : [ERREUR] fichier introuvable: $file"
|
||||
echo "########### $(date) : [ERREUR] voici les fichiers disponibles dans input/converted_to_wav: "
|
||||
echo " "
|
||||
ls -l input/converted_to_wav
|
||||
echo " "
|
||||
echo "########### $(date) : [ERREUR] le fichier $file n'existe PAS :C "
|
||||
exit 1
|
||||
fi
|
||||
echo " "
|
||||
FILE_NAME=$(basename $file .wav)
|
||||
OUT_DIR=$( echo "output/$FILE_NAME")
|
||||
mkdir output/$FILE_NAME
|
||||
|
||||
python3 ./conversion_simple_fr.py "$file" > $OUT_DIR/0_output.json
|
||||
mkdir -p "$OUT_DIR"
|
||||
echo " convertir en sous titre ? $ENABLE_SRT"
|
||||
if ($ENABLE_SRT) ; then
|
||||
echo "########### $(date) : conversion de $file ,sortie en fichier de sous titres .srt"
|
||||
echo ""
|
||||
echo "## (cela prend plusieurs minutes généralement 1 / 10ème du temps du fichier audio)"
|
||||
echo "..."
|
||||
python3 ./extract_srt.py "$file" > $OUT_DIR/6_output_$FILE_NAME.srt
|
||||
cat $OUT_DIR/6_output_$FILE_NAME.srt
|
||||
COUNT_LINES=$(cat $OUT_DIR/6_output_$FILE_NAME.srt |wc -l)
|
||||
echo " "
|
||||
echo "-------------- DONE ------------"
|
||||
echo " $COUNT_LINES lines in $OUT_DIR/6_phrases_min_sec.srt"
|
||||
else
|
||||
echo "########### $(date) : conversion de la sortie en divers fichiers marquant les temps et sans marquage"
|
||||
python3 ./conversion_simple_fr.py "$file" > $OUT_DIR/0_output_$FILE_NAME.json
|
||||
|
||||
echo " "
|
||||
echo "########### $(date) : nettoyer la sortie "
|
||||
jq .text $OUT_DIR/0_output_$FILE_NAME.json > $OUT_DIR/1_converted_$FILE_NAME.txt
|
||||
|
||||
sed 's/null//g' $OUT_DIR/1_converted_$FILE_NAME.txt > $OUT_DIR/2_without_nulls_$FILE_NAME.txt
|
||||
sed 's/^ *//; s/ *$//; /^$/d' $OUT_DIR/2_without_nulls_$FILE_NAME.txt > $OUT_DIR/3_without_nulls_$FILE_NAME.txt
|
||||
sed 's/\"//g' $OUT_DIR/3_without_nulls_$FILE_NAME.txt > $OUT_DIR/4_phrases_$FILE_NAME.txt
|
||||
echo "########### $(date) : OK "
|
||||
echo " "
|
||||
COUNT_LINES=$(cat $OUT_DIR/4_phrases_$FILE_NAME.txt |wc -l)
|
||||
cat $OUT_DIR/4_phrases_$FILE_NAME.txt
|
||||
echo " $COUNT_LINES lines in $OUT_DIR/4_phrases_$FILE_NAME.txt"
|
||||
echo " "
|
||||
echo "########### $(date) : lignes transcriptes $COUNT_LINES "
|
||||
echo "########### $(date) : conversion faite dans output/converted_out_without_nulls.txt"
|
||||
echo "########### $(date) : conversion de la sortie en pseudo fichier de sous titres"
|
||||
perl clean.sh $OUT_DIR/0_output_$FILE_NAME.json > $OUT_DIR/5_phrases_min_sec_$FILE_NAME.txt
|
||||
|
||||
|
||||
fi
|
||||
#ls -l $OUT_DIR
|
||||
|
||||
echo " "
|
||||
echo "########### $(date) : nettoyer la sortie "
|
||||
jq .text $OUT_DIR/0_output.json > $OUT_DIR/1_converted.txt
|
||||
|
||||
sed 's/null//g' $OUT_DIR/1_converted.txt > $OUT_DIR/2_without_nulls.txt
|
||||
sed 's/^ *//; s/ *$//; /^$/d' $OUT_DIR/2_without_nulls.txt > $OUT_DIR/3_without_nulls.txt
|
||||
sed 's/\"//g' $OUT_DIR/3_without_nulls.txt > $OUT_DIR/4_phrases.txt
|
||||
echo "########### $(date) : OK "
|
||||
echo " "
|
||||
COUNT_LINES=$(cat $OUT_DIR/phrases.txt |wc -l)
|
||||
cat $OUT_DIR/4_phrases.txt
|
||||
echo " "
|
||||
echo "########### $(date) : lignes transcriptes $COUNT_LINES "
|
||||
echo "########### $(date) : conversion faite dans output/converted_out_without_nulls.txt"
|
||||
echo "########### $(date) : conversion de la sortie en pseudo fichier de sous titres"
|
||||
perl clean.sh $OUT_DIR/0_output.json > $OUT_DIR/5_phrases_min_sec.txt
|
||||
cat $OUT_DIR/5_phrases_min_sec.srt
|
||||
|
||||
echo "########### $(date) : conversion de la sortie en fichier de sous titres "
|
||||
python3 ./extract_srt.py "$file" > $OUT_DIR/5_output.srt
|
||||
|
||||
ls -l $OUT_DIR
|
||||
|
||||
echo "########### $(date) : conversion faite "
|
||||
echo "########### $($STARTTIME) -- $(date) : conversion faite "
|
||||
echo "########### en $SECONDS seconds"
|
||||
exit 0
|
||||
|
14
vosk_builder.py
Normal file
14
vosk_builder.py
Normal file
@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
from cffi import FFI
|
||||
|
||||
vosk_root=os.environ.get("VOSK_SOURCE", "..")
|
||||
cpp_command = "cpp " + vosk_root + "/src/vosk_api.h"
|
||||
|
||||
ffibuilder = FFI()
|
||||
ffibuilder.set_source("vosk.vosk_cffi", None)
|
||||
ffibuilder.cdef(os.popen(cpp_command).read())
|
||||
|
||||
if __name__ == '__main__':
|
||||
ffibuilder.compile(verbose=True)
|
32
wav_to_wav_mono.sh
Executable file
32
wav_to_wav_mono.sh
Executable file
@ -0,0 +1,32 @@
|
||||
#!/bin/bash
|
||||
# utilisation: bash wav_to_wav.sh
|
||||
# auteur du script: tykayn contact@cipherbliss.com
|
||||
|
||||
echo "########### conversion des fichiers audio .wav placés dans le dossier input, vers du wav mono-piste uniquement dans le dossier input/converted_to_wav"
|
||||
echo " "
|
||||
cd input
|
||||
mkdir already_converted
|
||||
|
||||
for i in *.wav; do
|
||||
|
||||
echo "fichier à traiter: $i"
|
||||
ffmpeg -i "$i" -ac 1 "converted_to_wav/${i%wav}wav"
|
||||
|
||||
echo " converti en WAv, déplacement dans le dossier input/already_converted"
|
||||
mv "$i" already_converted/
|
||||
done
|
||||
|
||||
|
||||
echo " "
|
||||
echo "########### OK "
|
||||
echo "########### fichiers wav restant dans le dossier input "
|
||||
ls -l *.wav
|
||||
cd ..
|
||||
echo " "
|
||||
COUNT_LINES_ORIGIN=$(ls -l input/*.wav |wc -l)
|
||||
COUNT_LINES=$(ls -l input/converted_to_wav |wc -l)
|
||||
|
||||
echo "########### fichiers wav dans le dossier input: $COUNT_LINES_ORIGIN "
|
||||
echo "########### fichiers wav dans le dossier input/converted_to_wav: $COUNT_LINES "
|
||||
echo "########### conversion faite dans output/converted_out_without_nulls.txt"
|
||||
exit 0
|
24
webm_to_wav.sh
Executable file
24
webm_to_wav.sh
Executable file
@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
# utilisation: bash webm_to_wav.sh
|
||||
# auteur du script: tykayn contact@cipherbliss.com
|
||||
|
||||
echo "########### conversion des fichiers audio .webm placés dans le dossier input, vers du wav mono-piste uniquement dans le dossier input/converted_to_wav"
|
||||
echo " "
|
||||
cd input
|
||||
mkdir already_converted
|
||||
|
||||
|
||||
|
||||
echo " "
|
||||
echo "########### OK "
|
||||
echo "########### fichiers webm restant dans le dossier input "
|
||||
ls -l *.webm
|
||||
cd ..
|
||||
echo " "
|
||||
COUNT_LINES_ORIGIN=$(ls -l input/*.webm |wc -l)
|
||||
COUNT_LINES=$(ls -l input/converted_to_wav |wc -l)
|
||||
|
||||
echo "########### fichiers webm dans le dossier input: $COUNT_LINES_ORIGIN "
|
||||
echo "########### fichiers wav dans le dossier input/converted_to_wav: $COUNT_LINES "
|
||||
echo "########### conversion faite dans output/converted_out_without_nulls.txt"
|
||||
exit 0
|
25
website/_foot.php
Executable file
25
website/_foot.php
Executable file
@ -0,0 +1,25 @@
|
||||
</main>
|
||||
<section class="container footer has-background-black has-text-grey-light">
|
||||
<div class="columns">
|
||||
<div class="column">
|
||||
<h1 class="title is-2">Confidentialité</h1>
|
||||
ce site utilise youtube-dl pour récupérer la vidéo à transcrire et travailler dessus sur le serveur où cette page
|
||||
est installée.
|
||||
Ce site ne contient aucun tracker, les fichiers audio et vidéo téléchargés sont supprimés régulièrement, aucun usage de ce que vous mettez sur ce site autre que pour transcrire de l'audio n'est opéré.
|
||||
Vous pouvez aussi installer sur votre propre machine ce logiciel libre sous licence GNU affero v3.
|
||||
</div>
|
||||
<div class="column">
|
||||
<h1 class="title is-2">Sources</h1>
|
||||
<a href="https://forge.chapril.org/tykayn/transcription">
|
||||
Sources: Transcription sur la forge du chapril. </a>
|
||||
<br>Ceci est un logiciel libre, vous pouvez l'améliorer et examiner
|
||||
son fonctionnement comme bon vous semble.
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
13
website/_head.php
Executable file
13
website/_head.php
Executable file
@ -0,0 +1,13 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>
|
||||
Transcription vosk
|
||||
</title>
|
||||
<link rel="stylesheet" type="text/css" href="./bulma.min.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<main class='main'>
|
||||
<div class="container">
|
||||
|
||||
<h1 class="title is-2">Transcription Vosk</h1>
|
||||
</div>
|
1
website/bulma.min.css
vendored
Executable file
1
website/bulma.min.css
vendored
Executable file
File diff suppressed because one or more lines are too long
134
website/download.php
Executable file
134
website/download.php
Executable file
@ -0,0 +1,134 @@
|
||||
<?php
|
||||
include( '_head.php' );
|
||||
?>
|
||||
<div class="container">
|
||||
|
||||
<?php
|
||||
/**
|
||||
* récupération d'une vidéo par youtube dl et conversion
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @param $cmd
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function command_exist( $cmd ) {
|
||||
$return = shell_exec( sprintf( "which %s", escapeshellarg( $cmd ) ) );
|
||||
|
||||
return ! empty( $return );
|
||||
}
|
||||
|
||||
if ( isset( $_POST[ 'url' ] ) ) {
|
||||
// sanitize input
|
||||
|
||||
$url = $_POST[ 'url' ];
|
||||
$lang = isset($_POST[ 'lang' ]) ? $_POST['lang'] : 'fr';
|
||||
|
||||
echo "<br/>récupération de la vidéo à l'url " . $url . " ... <br>";
|
||||
|
||||
// if (!command_exist('youtube-dl')) {
|
||||
// print '[Erreur] pas de commande youtube-dl installée sur ce serveur';
|
||||
// } else {
|
||||
|
||||
// $uniqid = date( 'Y-M-d_' ) . time();
|
||||
$uniqid = 'demo_video_tk';
|
||||
|
||||
// # exemple url https://peertube.cipherbliss.com/videos/watch/e6a37508-042e-4d83-8598-5d36b764bb3d
|
||||
|
||||
|
||||
if (file_exists('../input/ydl/'.$uniqid)) {
|
||||
echo "The file $filename exists";
|
||||
}else{
|
||||
|
||||
|
||||
|
||||
// exec( './youtube-dl.sh uniqueid_facho https://peertube.cipherbliss.com/videos/watch/b88a9568-517c-4a49-ab07-75c79323a825', $output, $result );
|
||||
exec( './youtube-dl.sh ' . $uniqid . ' ' . $url . ' ' . $lang, $output, $result );
|
||||
|
||||
$phrases_only = file_get_contents( '../input/ydl/' . $uniqid . '/3_without_nulls.txt' );
|
||||
|
||||
echo "<br/> résultat du script. <br><pre>";
|
||||
var_dump( $result );
|
||||
echo "</pre><br/> output du script. <br><pre>";
|
||||
var_dump( $output );
|
||||
echo "</pre>";
|
||||
|
||||
|
||||
if ( $result ) {
|
||||
echo '<div class="alert is-danger"> </div>
|
||||
<article class="message is-danger">
|
||||
<div class="message-header">
|
||||
<p>Problème de script</p>
|
||||
<button class="delete" aria-label="delete"></button>
|
||||
</div>
|
||||
<div class="message-body">
|
||||
<h2 class="title is2">
|
||||
Sortie du script:
|
||||
</h2><br> <br>
|
||||
';
|
||||
var_dump( $output );
|
||||
echo '
|
||||
</div>
|
||||
</article>
|
||||
';
|
||||
include( '_foot.php' );
|
||||
}
|
||||
// récup du nom de fichier
|
||||
echo '<article class="message is-info">
|
||||
<div class="message-body">
|
||||
récupération de la piste audio OK.
|
||||
</div>
|
||||
</article>';
|
||||
|
||||
|
||||
echo "<br/>Conversion de la vidéo " . $uniqid . "... <br>";
|
||||
|
||||
}
|
||||
echo '<article class="message is-success">
|
||||
<div class="message-header">
|
||||
<p>Succès</p>
|
||||
<button class="delete" aria-label="delete"></button>
|
||||
</div>
|
||||
<div class="message-body">
|
||||
Vous pouvez télécharger vos fichiers.
|
||||
<ul>
|
||||
<li>
|
||||
<a href='../input/ydl/'.$uniqid.'/4_phrases_.txt'>phrases txt</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</article><br>
|
||||
<article class="message is-info">
|
||||
<div class="message-header">
|
||||
<p>Texte avec uniquement les phrases</p>
|
||||
<button class="delete" aria-label="delete"></button>
|
||||
</div>
|
||||
<div class="message-body">
|
||||
' . $phrases_only . '
|
||||
</div>
|
||||
</article>
|
||||
<hr>
|
||||
<br>
|
||||
TODO: <br>
|
||||
texte avec horodatage minute et secondes avant les phrases. <br>
|
||||
fichier de sous titres au standard srt <br>
|
||||
';
|
||||
|
||||
$dir = scandir( '../input/ydl/' . $uniqid );
|
||||
var_dump( $dir );
|
||||
// }
|
||||
|
||||
|
||||
} else {
|
||||
echo " <br> pas d'url envoyée. Vérifiez le formulaire. <a href='index.php'>Retour</a>";
|
||||
}
|
||||
|
||||
// exec( './youtube-dl.sh canadien https://www.youtube.com/watch?v=w97pAEr3svc', $output, $result );
|
||||
|
||||
?>
|
||||
|
||||
</div>
|
||||
<?php
|
||||
include( '_foot.php' );
|
27
website/index.php
Executable file
27
website/index.php
Executable file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
include( '_head.php' );
|
||||
?>
|
||||
<section class="hero is-info is-large">
|
||||
<div class="hero-body">
|
||||
<div class="container">
|
||||
|
||||
<p class="title">
|
||||
Conversion d'audio ou de vidéo en texte
|
||||
</p>
|
||||
<p class="subtitle">
|
||||
Transcrire en Français avec une URL
|
||||
<form action='download.php' method='post'>
|
||||
<input class="input is-block" type='text' name='url'
|
||||
value="https://peertube.cipherbliss.com/videos/watch/e6a37508-042e-4d83-8598-5d36b764bb3d">
|
||||
<br>
|
||||
<button class="button is-primary" type='submit'>Envoyer</button>
|
||||
</form>
|
||||
</div>
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
<?php
|
||||
include( '_foot.php' );
|
||||
?>
|
4
website/info.php
Executable file
4
website/info.php
Executable file
@ -0,0 +1,4 @@
|
||||
<?php
|
||||
|
||||
echo exec('website/test.sh');
|
||||
|
21
website/log_ydl.txt
Executable file
21
website/log_ydl.txt
Executable file
@ -0,0 +1,21 @@
|
||||
sam. 27 mars 2021 10:27:21 CET ###### start conversion __ essai __ https://peertube.cipherbliss.com/videos/watch/e6a37508-042e-4d83-8598-5d36b764bb3d
|
||||
sam. 27 mars 2021 10:30:16 CET ###### start conversion __ essai __ https://peertube.cipherbliss.com/videos/watch/e6a37508-042e-4d83-8598-5d36b764bb3d
|
||||
Sat Mar 27 13:50:27 CET 2021 ###### start conversion __ essai.wav __ https://peertube.cipherbliss.com/videos/watch/e6a37508-042e-4d83-8598-5d36b764bb3d
|
||||
Sat Mar 27 14:00:20 CET 2021 ###### start conversion __ essai.wav __ https://peertube.cipherbliss.com/videos/watch/e6a37508-042e-4d83-8598-5d36b764bb3d
|
||||
Sat Mar 27 14:02:25 CET 2021 ###### start conversion __ essai __ https://peertube.cipherbliss.com/videos/watch/e6a37508-042e-4d83-8598-5d36b764bb3d
|
||||
Sat Mar 27 14:03:13 CET 2021 ###### start conversion __ essai __ https://peertube.cipherbliss.com/videos/watch/e6a37508-042e-4d83-8598-5d36b764bb3d
|
||||
Sat Mar 27 14:03:52 CET 2021 ###### start conversion __ essai __ https://peertube.cipherbliss.com/videos/watch/e6a37508-042e-4d83-8598-5d36b764bb3d
|
||||
Sat Mar 27 14:23:15 CET 2021 ###### start conversion __ batman_script __ https://peertube.cipherbliss.com/videos/watch/193545b2-3cd5-468a-b563-e17d0121e1bf
|
||||
Sat Mar 27 14:23:18 CET 2021 ###### end conversion __ batman_script __ https://peertube.cipherbliss.com/videos/watch/193545b2-3cd5-468a-b563-e17d0121e1bf
|
||||
Sat Mar 27 14:24:10 CET 2021 ###### start conversion __ batman_script __ https://peertube.cipherbliss.com/videos/watch/193545b2-3cd5-468a-b563-e17d0121e1bf
|
||||
Sat Mar 27 14:43:29 CET 2021 ###### start conversion __ 2021-Mar-27_1616852609 __ https://peertube.cipherbliss.com/videos/watch/e6a37508-042e-4d83-8598-5d36b764bb3d
|
||||
Sat Mar 27 21:48:44 CET 2021 ###### start conversion __ 2021-Mar-27_1616878123 __ https://peertube.cipherbliss.com/videos/watch/e6a37508-042e-4d83-8598-5d36b764bb3d
|
||||
Tue Apr 20 17:19:12 CEST 2021 ###### start conversion __ 2021-Apr-20_1618931951 __ https://peertube.cipherbliss.com/videos/watch/e6a37508-042e-4d83-8598-5d36b764bb3d
|
||||
Tue Apr 20 17:37:28 CEST 2021 ###### start conversion __ 2021-Apr-20_1618933048 __ https://peertube.cipherbliss.com/videos/watch/e6a37508-042e-4d83-8598-5d36b764bb3d
|
||||
Wed Aug 18 16:09:49 CEST 2021 ###### start conversion __ 2021-Aug-18_1629295789 __ https://peertube.cipherbliss.com/videos/watch/e6a37508-042e-4d83-8598-5d36b764bb3d
|
||||
Wed Aug 18 16:10:48 CEST 2021 ###### start conversion __ 2021-Aug-18_1629295848 __ https://peertube.cipherbliss.com/videos/watch/e6a37508-042e-4d83-8598-5d36b764bb3d
|
||||
Wed Aug 18 16:12:10 CEST 2021 ###### start conversion __ 2021-Aug-18_1629295930 __ https://peertube.cipherbliss.com/videos/watch/e6a37508-042e-4d83-8598-5d36b764bb3d
|
||||
Wed Aug 18 16:14:13 CEST 2021 ###### start conversion __ demo_video_tk __ https://peertube.cipherbliss.com/videos/watch/e6a37508-042e-4d83-8598-5d36b764bb3d
|
||||
Wed Aug 18 16:15:53 CEST 2021 ###### start conversion __ demo_video_tk __ https://peertube.cipherbliss.com/videos/watch/e6a37508-042e-4d83-8598-5d36b764bb3d
|
||||
Wed Aug 18 16:16:15 CEST 2021 ###### start conversion __ demo_video_tk __ https://peertube.cipherbliss.com/videos/watch/e6a37508-042e-4d83-8598-5d36b764bb3d
|
||||
Wed Aug 18 16:17:20 CEST 2021 ###### start conversion __ demo_video_tk __ https://peertube.cipherbliss.com/videos/watch/e6a37508-042e-4d83-8598-5d36b764bb3d
|
5
website/run.php
Executable file
5
website/run.php
Executable file
@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
exec( './youtube-dl.sh uniqueid_facho https://peertube.cipherbliss.com/videos/watch/b88a9568-517c-4a49-ab07-75c79323a825', $output,$result);
|
||||
var_dump($output);
|
||||
var_dump($result);
|
3
website/test.sh
Executable file
3
website/test.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo " coucou" > test_works.txt
|
1
website/test_works.txt
Executable file
1
website/test_works.txt
Executable file
@ -0,0 +1 @@
|
||||
coucou
|
41
website/youtube-dl.sh
Executable file
41
website/youtube-dl.sh
Executable file
@ -0,0 +1,41 @@
|
||||
#!/bin/bash
|
||||
touch log_ydl.txt
|
||||
echo " $(date) ###### start conversion __ $1 __ $2" >> log_ydl.txt
|
||||
UNIQID=$1
|
||||
|
||||
# mkdir -p ../input/ydl
|
||||
# rm -rf ../input/ydl/$UNIQID.mp3
|
||||
# rm -rf ../input/ydl/$UNIQID
|
||||
|
||||
URL=$2
|
||||
OUTPUT="../input/ydl/$UNIQID/base.mp3"
|
||||
|
||||
echo " \n output : \n"
|
||||
echo $OUTPUT
|
||||
|
||||
mkdir ../input/ydl/$UNIQID
|
||||
youtube-dl --extract-audio --audio-format mp3 --audio-quality 0 --output $OUTPUT $URL --no-continue
|
||||
|
||||
ls -larth ../input/ydl/$UNIQID
|
||||
|
||||
ffmpeg -i "../input/ydl/$UNIQID/base.mp3" -ac 1 "../input/ydl/$UNIQID/mono_canal.wav"
|
||||
|
||||
OUT_DIR="input/ydl/$UNIQID"
|
||||
mkdir $OUT_DIR
|
||||
|
||||
echo " $(date) ###### lancer la transcription"
|
||||
pwd
|
||||
ls -larth input/ydl/$UNIQID/
|
||||
echo "\n"
|
||||
|
||||
cd ..
|
||||
bash transcript.sh input/ydl/$UNIQID/mono_canal.wav
|
||||
|
||||
#jq .text $OUT_DIR/0_output_$FILE_NAME.json > $OUT_DIR/1_converted_$FILE_NAME.txt
|
||||
# sed 's/null//g' $OUT_DIR/1_converted_$FILE_NAME.txt > $OUT_DIR/2_without_nulls_$FILE_NAME.txt
|
||||
# sed 's/^ *//; s/ *$//; /^$/d' $OUT_DIR/2_without_nulls_$FILE_NAME.txt > $OUT_DIR/3_without_nulls_$FILE_NAME.txt
|
||||
# sed 's/\"//g' $OUT_DIR/3_without_nulls_$FILE_NAME.txt > $OUT_DIR/4_phrases_$FILE_NAME.txt
|
||||
|
||||
ls -l $OUT_DIR >> log_ydl.txt
|
||||
echo " $(date) ###### end conversion __ $1 __ $2" >> log_ydl.txt
|
||||
|
Loading…
Reference in New Issue
Block a user