Compare commits
3 Commits
8933e8dd86
...
6fa0d0936b
Author | SHA1 | Date | |
---|---|---|---|
6fa0d0936b | |||
dccdc96146 | |||
2347a998c5 |
216
README.md
216
README.md
|
@ -1,3 +1,215 @@
|
|||
# sboby
|
||||
# sboby - Trascrivere una registrazione audio
|
||||
|
||||
Trascrivere una registrazione audio
|
||||
*Sbobinare, parola amara.*
|
||||
|
||||
![sboby](sboby.jpg){ width=90% }
|
||||
|
||||
Il metodo gramo, passo passo ma così educazionale che ti sale la gioia.
|
||||
Feel free di saltare le parti ovvie o di arredare il tunnel come meglio si crede.
|
||||
|
||||
Funziona con Debian 11 stable.
|
||||
|
||||
# Installare il software che useremo:
|
||||
|
||||
sudo apt install python3 ffmpeg unzip mediainfo
|
||||
|
||||
Lanciare un terminale e creare una directory dove lavorare con il file ad esempio: audio.mp3
|
||||
|
||||
mkdir ~/sbobina
|
||||
cd ~/sbobina/
|
||||
|
||||
ls
|
||||
|
||||
`audio.mp3`
|
||||
|
||||
# Convertire il file in mp4
|
||||
|
||||
ffmpeg -i audio.mp3 audio.mp4
|
||||
|
||||
# Se il file è molto lungo
|
||||
|
||||
*es: più di due ore e mezzo*
|
||||
|
||||
Sarà utile spezzarlo in più parti, sennò lo script potrebbe fallire perché
|
||||
gli finisce la memoria, ma non gliene faremo una colpa.
|
||||
|
||||
Sapere quanto dura:
|
||||
|
||||
mediainfo audio.mp4 | grep Duration
|
||||
|
||||
`Duration: 2 h 00 min`
|
||||
|
||||
In questo esempio il file esattamente dura due ore e lo si vuole dividere in due
|
||||
parti di un'ora ciascuna:
|
||||
|
||||
ffmpeg -ss 00:00:00 -t 01:00:00 -i audio.mp4 -vcodec copy -acodec copy audio-0-1.mp4
|
||||
|
||||
ffmpeg -ss 00:01:00 -t 01:00:00 -i audio.mp4 -vcodec copy -acodec copy audio-1-2.mp4
|
||||
|
||||
ls
|
||||
|
||||
```
|
||||
audio.mp3
|
||||
audio.mp4
|
||||
audio-0-1.mp4
|
||||
audio-1-2.mp4
|
||||
```
|
||||
|
||||
# Trascrivere i file
|
||||
|
||||
Per trascrivere (o sbobinare), si installeranno videogrep e vosk
|
||||
|
||||
pip3 install videogrep
|
||||
|
||||
pip3 install vosk
|
||||
|
||||
# Modulo lingua italiana per Vosk
|
||||
|
||||
Scaricare e scompattare il modulo lingua italiana per Vosk
|
||||
|
||||
wget https://alphacephei.com/vosk/models/vosk-model-small-it-0.4.zip
|
||||
|
||||
unzip vosk-model-small-it-0.4.zip
|
||||
|
||||
# Trascrivere
|
||||
|
||||
la prima ora:
|
||||
|
||||
videogrep --input audio-0-1.mp4 --model vosk-model-small-it-0.4/ --transcribe
|
||||
|
||||
Durata della conversione: circa 15 minuti. La durata dipenderà dalla potenza del PC usato.
|
||||
|
||||
la seconda ora:
|
||||
|
||||
videogrep --input audio-1-2.mp4 --model vosk-model-small-it-0.4/ --transcribe
|
||||
|
||||
Si ottengono due JSON file
|
||||
|
||||
ls
|
||||
|
||||
```
|
||||
audio-0-1.json
|
||||
audio-1-2.json
|
||||
```
|
||||
|
||||
I JSON file sono comodissimi dal punto di vista di una macchina. Se lo scopo
|
||||
della trascrizione è editare il video usando videogrep, si può procedere. Tra i
|
||||
link c'è il tutorial di videogrep.
|
||||
|
||||
Se lo scopo è farne dei sottotitoli, occorrerà convertire da JSON in SRT o XML.
|
||||
|
||||
Ma in questo caso siamo umani, si vuole ottenere del testo semplice da
|
||||
allegare alla registrazione per ricerca e archivio (and for great justice).
|
||||
|
||||
Here comes Bomboclat, il quale ha scritto questo piccolo script che converte
|
||||
(guarda un po') un JSON in un SRT.
|
||||
|
||||
# Convertire da JSON a SRT
|
||||
|
||||
Ecco lo script [json2srt](json2srt.py)
|
||||
|
||||
Per l'utilizzo lasciamo la parola a Bomboclat, cui rendiamo merito:
|
||||
|
||||
```
|
||||
sudo apt install python3-venv
|
||||
nella tua home dai questo comando
|
||||
python3 -m venv json_to_srt
|
||||
ti crea una cartella json_to_srt
|
||||
con dentro python3
|
||||
fatto questo comando ne dai un altro per attivarlo
|
||||
source ~/json_to_srt/bin/activate
|
||||
a sto punto hai lo script che ora ti passo aggiornato
|
||||
ha ancora un difetto, le ore sono espresse con una cifra
|
||||
percio' anziche' scrivere per esempio:
|
||||
00:00:00,000
|
||||
ore minuti secondi, millesimi
|
||||
scrive solo
|
||||
0:00:00,000
|
||||
che si risolve facile
|
||||
aggiungendo lo 0 a mano nella stringa finale
|
||||
ma per ora lasciamo perdere sto dettaglio
|
||||
python json2srt.py -i un_file.json -o il_suo_output.srt
|
||||
```
|
||||
|
||||
A me mi funziona anche solo mettendo lo script in ~/bin e dandogli i permessi di esecuzione:
|
||||
|
||||
mv json2srt.py ~/bin/
|
||||
chmod 755 ~/bin/json2srt.py
|
||||
|
||||
Però è anche vero che non si dice: "a me mi", dunque anche il vostro
|
||||
chilometraggio potrebbe variare.
|
||||
|
||||
Una volta installato lo script, si può fare la conversione da JSON a SRT.
|
||||
|
||||
Tornando al nostro esempio:
|
||||
|
||||
json2srt.py -i audio-0-1.json -o audio-0-1.srt
|
||||
|
||||
json2srt.py -i audio-1-2.json -o audio-1-2.srt
|
||||
|
||||
Ora si potranno ricongiungere i due file, finalmente.
|
||||
|
||||
cat audio-0-1.srt audio-1-2.srt > audio.srt
|
||||
|
||||
E così ottenere l'agognato file:
|
||||
|
||||
`audio.srt'
|
||||
|
||||
# Il file audio.SRT
|
||||
|
||||
Un file SRT è testo puro e si presenta così:
|
||||
|
||||
1
|
||||
0:00:01,680 --> 0:00:06,810
|
||||
bla bla bla bla, bla bla bla
|
||||
|
||||
2
|
||||
0:00:08,372 --> 0:00:13,830
|
||||
bla bla bla bla e ancora bla
|
||||
|
||||
|
||||
cioè:
|
||||
|
||||
* Numeroriga
|
||||
* Timecode
|
||||
* Testo
|
||||
* Spazio
|
||||
|
||||
È già umanamente leggibile, ma per poterlo pubblicare come testo semplice si
|
||||
potranno togliere le righe che contengono, come espressioni regolari, Numeroriga
|
||||
e Timecode.
|
||||
|
||||
sed '/[0-9]/d' audio.srt > trascrizione.txt
|
||||
|
||||
Ed eventualmente anche levare la riga vuota!
|
||||
|
||||
sed '/^$/d' trascrizione.txt > wallof.txt
|
||||
|
||||
Poi rileggere, riascoltare e correggere.
|
||||
|
||||
# Share and enjoy
|
||||
|
||||
Shoutz a Debian, ffmpeg, videogrep e vosk, Bomboclat per lo script, ilLobo per
|
||||
aver scoperto videogrep, dan che ha scritto e Shoutz a te che leggi, possa la
|
||||
sbobinatura esserti lieve.
|
||||
|
||||
This is a: DIWO (Do It With Others)
|
||||
|
||||
**WE ARE NOT MEN! WE ARE DIWO!**
|
||||
|
||||
# Links
|
||||
|
||||
Debian GNU/Linux Free OS
|
||||
https://www.debian.org/
|
||||
|
||||
ffmpeg
|
||||
https://ffmpeg.org/
|
||||
|
||||
Videogrep Tutorial
|
||||
https://lav.io/notes/videogrep-tutorial/
|
||||
|
||||
Vosk speech recognition toolkit
|
||||
https://alphacephei.com/vosk/
|
||||
|
||||
Vosk models
|
||||
https://alphacephei.com/vosk/models
|
||||
|
|
79
json2srt.py
Executable file
79
json2srt.py
Executable file
|
@ -0,0 +1,79 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
# by Bomboclat
|
||||
|
||||
# for great justice!
|
||||
|
||||
import sys
|
||||
import json
|
||||
import argparse
|
||||
from datetime import timedelta
|
||||
|
||||
|
||||
def convert(seconds):
|
||||
sec_to_convert = seconds
|
||||
converted_sec = timedelta(seconds = sec_to_convert)
|
||||
dot = str(converted_sec).find('.')
|
||||
if dot != -1:
|
||||
timestamp = str(converted_sec)[:-3].replace('.',',')
|
||||
else:
|
||||
timestamp = str(converted_sec).replace('.',',')
|
||||
|
||||
return timestamp
|
||||
|
||||
|
||||
def write_file(srt, outfile):
|
||||
for d in srt:
|
||||
with open(outfile, 'a') as f:
|
||||
for value in d.values():
|
||||
f.write('%s\n' % (str(value)))
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
def json_to_srt(f):
|
||||
'''
|
||||
SRT file format:
|
||||
|
||||
sequence number
|
||||
two-hash arrow to separate beginning and ending timecodes
|
||||
caption
|
||||
empty line
|
||||
|
||||
example:
|
||||
1
|
||||
00:00:00,000 --> 00:00:04,440
|
||||
here the subtitle caption string
|
||||
|
||||
2
|
||||
-8<--snip!--
|
||||
'''
|
||||
srt = []
|
||||
for d in f:
|
||||
sequence_number = f.index(d) + 1
|
||||
startstop = convert(float(d['start'])) + " --> " + convert(float(d['end']))
|
||||
#print(startstop)
|
||||
new_sub = { 'seq': sequence_number, 'startstop': startstop, 'caption': d['content'], 'newline': '' }
|
||||
srt.append(new_sub)
|
||||
|
||||
return srt
|
||||
|
||||
|
||||
def main():
|
||||
# parse command line options
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('-i', '--infile', help='input file in json format', type=argparse.FileType('r'))
|
||||
parser.add_argument('-o', '--outfile', action='store', dest='outfile', help="Directs the output to a name of your choice")
|
||||
args = parser.parse_args()
|
||||
|
||||
# loads a list of dicts
|
||||
f = json.load(args.infile)
|
||||
outfile = args.outfile
|
||||
srt = json_to_srt(f)
|
||||
write_file(srt, outfile)
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
Loading…
Reference in New Issue
Block a user