Added: vosk functionality
This commit is contained in:
parent
f4dcd34574
commit
118ba785e2
@ -4,59 +4,21 @@
|
||||
# this file is released under public domain and you can use without limitations
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
#from transcription_tools import create_vtt
|
||||
transcription_tools = local_import('transcription_tools', reload=True)
|
||||
|
||||
# ---- example index page ----
|
||||
def index():
|
||||
images = db().select(db.image.ALL, orderby=db.image.title)
|
||||
return dict(images=images)
|
||||
media_files = db().select(db.media_file.ALL, orderby=db.media_file.title)
|
||||
return dict(media_files=media_files)
|
||||
|
||||
@auth.requires_membership('manager')
|
||||
def manage():
|
||||
grid = SQLFORM.smartgrid(db.image, linked_tables=['post'])
|
||||
grid = SQLFORM.smartgrid(db.media_file, linked_tables=['post'])
|
||||
return dict(grid=grid)
|
||||
|
||||
# ---- API (example) -----
|
||||
@auth.requires_login()
|
||||
def api_get_user_email():
|
||||
if not request.env.request_method == 'GET': raise HTTP(403)
|
||||
return response.json({'status':'success', 'email':auth.user.email})
|
||||
def vtt():
|
||||
return dict(message=transcription_tools.create_vtt())
|
||||
|
||||
# ---- Smart Grid (example) -----
|
||||
@auth.requires_membership('admin') # can only be accessed by members of admin groupd
|
||||
def grid():
|
||||
response.view = 'generic.html' # use a generic view
|
||||
tablename = request.args(0)
|
||||
if not tablename in db.tables: raise HTTP(403)
|
||||
grid = SQLFORM.smartgrid(db[tablename], args=[tablename], deletable=False, editable=False)
|
||||
return dict(grid=grid)
|
||||
|
||||
# ---- Embedded wiki (example) ----
|
||||
def wiki():
|
||||
auth.wikimenu() # add the wiki to the menu
|
||||
return auth.wiki()
|
||||
|
||||
# ---- Action for login/register/etc (required for auth) -----
|
||||
def user():
|
||||
"""
|
||||
exposes:
|
||||
http://..../[app]/default/user/login
|
||||
http://..../[app]/default/user/logout
|
||||
http://..../[app]/default/user/register
|
||||
http://..../[app]/default/user/profile
|
||||
http://..../[app]/default/user/retrieve_password
|
||||
http://..../[app]/default/user/change_password
|
||||
http://..../[app]/default/user/bulk_register
|
||||
use @auth.requires_login()
|
||||
@auth.requires_membership('group name')
|
||||
@auth.requires_permission('read','table name',record_id)
|
||||
to decorate functions that need access control
|
||||
also notice there is http://..../[app]/appadmin/manage/auth to allow administrator to manage users
|
||||
"""
|
||||
return dict(form=auth())
|
||||
|
||||
# ---- action to server uploaded static content (required) ---
|
||||
@cache.action()
|
||||
def download():
|
||||
"""
|
||||
allows downloading of uploaded files
|
||||
http://..../[app]/default/download/[filename]
|
||||
"""
|
||||
return response.download(request, db)
|
||||
|
@ -1,8 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
{
|
||||
'!=': '!=',
|
||||
'!langcode!': 'de',
|
||||
'!langname!': 'Deutsch (DE)',
|
||||
'"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN': '"Update" ist ein optionaler Ausdruck wie "feld1=\'newvalue\'". JOIN Ergebnisse können nicht aktualisiert oder gelöscht werden',
|
||||
'%(nrows)s records found': '%(nrows)s records found',
|
||||
'%s %%{row} deleted': '%s %%{row} gelöscht',
|
||||
'%s %%{row} updated': '%s %%{row} aktualisiert',
|
||||
'%s selected': '%s ausgewählt',
|
||||
@ -12,6 +14,13 @@
|
||||
'**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** %%{Item(Items)}, **%(bytes)s** %%{Byte(Bytes)}',
|
||||
'**%(items)s** items, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** Items, **%(bytes)s** %%{Byte(Bytes)}',
|
||||
'**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)': '**nicht verfügbar** (benötigt die Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] Bibliothek)',
|
||||
'+ And': '+ And',
|
||||
'+ Or': '+ Or',
|
||||
'<': '<',
|
||||
'<=': '<=',
|
||||
'=': '=',
|
||||
'>': '>',
|
||||
'>=': '>=',
|
||||
'?': '?',
|
||||
'@markmin\x01(**%.0d MB**)': '(**%.0d\xa0MB**)',
|
||||
'@markmin\x01**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}': '**%(items)s** %%{Item(items)}, **%(bytes)s** %%{Byte(bytes)}',
|
||||
@ -28,6 +37,10 @@
|
||||
'A new password was emailed to you': 'Ein neues Passwort wurde per E-Mail an Sie gesendet',
|
||||
'About': 'Über',
|
||||
'Access Control': 'Zugangskontrolle',
|
||||
'Add Record': 'Add Record',
|
||||
'Add record to database': 'Add record to database',
|
||||
'Add this to the search as an AND term': 'Add this to the search as an AND term',
|
||||
'Add this to the search as an OR term': 'Add this to the search as an OR term',
|
||||
'admin': 'admin',
|
||||
'Ajax Recipes': 'Ajax Rezepte',
|
||||
'An error occured, please [[reload %s]] the page': 'Ein Fehler ist aufgetreten, bitte [[laden %s]] Sie die Seite neu',
|
||||
@ -37,6 +50,7 @@
|
||||
'Are you sure you want to delete this object?': 'Sind Sie sich sicher, dass Sie dieses Objekt löschen wollen?',
|
||||
'Authentication code': 'Authentifizierungs code',
|
||||
'Available Databases and Tables': 'Verfügbare Datenbanken und Tabellen',
|
||||
'Back': 'Back',
|
||||
"Buy web2py's book": "web2py's Buch kaufen",
|
||||
'Cache': 'Zwischenspeicher',
|
||||
'cache': 'zwischenspeicher',
|
||||
@ -44,20 +58,27 @@
|
||||
'Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.': 'Cache enthält items die bis zu **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} alt sind.',
|
||||
'Cache Keys': 'Cache Schlüssel',
|
||||
'Cannot be empty': 'Darf nicht leer sein',
|
||||
'Change Password': 'Canviï la Contrasenya',
|
||||
'Change Password': 'Passwort ändern',
|
||||
'Change password': 'Canviï la contrasenya',
|
||||
'Check to delete': 'Auswählen um zu löschen',
|
||||
'Clear': 'Clear',
|
||||
'Clear CACHE?': 'CACHE löschen?',
|
||||
'Clear DISK': 'DISK löschen',
|
||||
'Clear RAM': 'RAM löschen',
|
||||
'Click on the link %(link)s to reset your password': 'Klicke auf den Link %(link)s um das Passwort zurückzusetzen',
|
||||
'Client IP': 'Client IP',
|
||||
'Close': 'Close',
|
||||
'Comma-separated export including columns not shown; fields from other tables are exported as raw values for faster export': 'Comma-separated export including columns not shown; fields from other tables are exported as raw values for faster export',
|
||||
'Comma-separated export of visible columns. Fields from other tables are exported as they appear on-screen but this may be slow for many rows': 'Comma-separated export of visible columns. Fields from other tables are exported as they appear on-screen but this may be slow for many rows',
|
||||
'Community': 'Community',
|
||||
'Components and Plugins': 'Komponenten und Plugins',
|
||||
'Config.ini': 'Config.ini',
|
||||
'Confirm Password': 'Passwort bestätigen',
|
||||
'contains': 'contains',
|
||||
'Controller': 'Controller',
|
||||
'Copyright': 'Urheberrechte',
|
||||
'CSV': 'CSV',
|
||||
'CSV (hidden cols)': 'CSV (hidden cols)',
|
||||
'Current request': 'Derzeitiger Request',
|
||||
'Current response': 'Derzeitige Response',
|
||||
'Current session': 'Derzeitige Session',
|
||||
@ -67,6 +88,7 @@
|
||||
'Database Administration (appadmin)': 'Datenbankadministration (appadmin)',
|
||||
'db': 'db',
|
||||
'DB Model': 'Muster-DB',
|
||||
'Delete': 'Delete',
|
||||
'Delete:': 'Lösche:',
|
||||
'Demo': 'Demo',
|
||||
'Deployment Recipes': 'Entwicklungsrezepte',
|
||||
@ -82,6 +104,8 @@
|
||||
'done!': 'Fertig!',
|
||||
'Download': 'Download',
|
||||
'E-mail': 'Email',
|
||||
'Edit': 'Edit',
|
||||
'Edit %(entity)s': 'Edit %(entity)s',
|
||||
'Edit current record': 'Diesen Eintrag editieren',
|
||||
'Email and SMS': 'Email und SMS',
|
||||
'Email sent': 'Email gesendet',
|
||||
@ -89,7 +113,11 @@
|
||||
'Email verified': 'Email-Verifiziert',
|
||||
'Errors': 'Fehlermeldungen',
|
||||
'export as csv file': 'als csv Datei exportieren',
|
||||
'Export:': 'Export:',
|
||||
'FAQ': 'FAQ',
|
||||
'file': 'file',
|
||||
'file ## download': 'file ',
|
||||
'File Filename': 'File Filename',
|
||||
'First name': 'Vorname',
|
||||
'Forms and Validators': 'Forms und Validators',
|
||||
'Free Applications': 'Kostenlose Anwendungen',
|
||||
@ -98,7 +126,7 @@
|
||||
'Grid Example': 'Rasterbeispiel',
|
||||
'Group %(group_id)s created': 'Grupo %(group_id)s creat',
|
||||
'Group %(group_id)s deleted': 'Gruppe %(group_id)s gelöscht',
|
||||
'Group ID': 'ID de Grup',
|
||||
'Group ID': 'ID Benutzergruppe',
|
||||
'Group uniquely assigned to user %(id)s': 'Gruppe eindeutig dem Benutzer zugewiesen %(id)s',
|
||||
'Groups': 'Gruppen',
|
||||
'Hello World': 'Hallo Welt',
|
||||
@ -106,10 +134,15 @@
|
||||
'Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})': 'Trefferquote: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} und **%(misses)s** %%{miss(misses)})',
|
||||
'Home': 'Startseite',
|
||||
'How did you get here?': 'Wie sind Sie hier her gelangt?',
|
||||
'HTML': 'HTML',
|
||||
'HTML export of visible columns': 'HTML export of visible columns',
|
||||
'Id': 'Id',
|
||||
'Images': 'Images',
|
||||
'import': 'Importieren',
|
||||
'Import/Export': 'Importieren/Exportieren',
|
||||
'in': 'in',
|
||||
'Incorrect code. {0} more attempt(s) remaining.': 'Falscher Code. {0} weitere Versuche verbleiben.',
|
||||
'Insufficient privileges': 'Privilegis insuficients',
|
||||
'Insufficient privileges': 'Unzureichende Berechtigungen',
|
||||
'Internal State': 'Innerer Zustand',
|
||||
'Introduction': 'Einführung',
|
||||
'Invalid email': 'Ungültige Email',
|
||||
@ -122,6 +155,8 @@
|
||||
'Invalid user': 'Ungültiger Benutzer',
|
||||
'Invalid username': 'Ungültiger Benutzername',
|
||||
'Invitation to join %(site)s': 'Einladung um %(site)s zujoinen',
|
||||
'JSON': 'JSON',
|
||||
'JSON export of visible columns': 'JSON export of visible columns',
|
||||
'Key': 'Schlüssel',
|
||||
'Key verified': 'Schlüssel verifiziert',
|
||||
'Last name': 'Nachname',
|
||||
@ -138,15 +173,22 @@
|
||||
'Manage %(action)s': '%(action)s verwalten',
|
||||
'Manage Access Control': 'Zugangskontrolle verwalten',
|
||||
'Manage Cache': 'Cache verwalten',
|
||||
'Media files': 'Media files',
|
||||
'Memberships': 'Mitgliedschaften',
|
||||
'Menu Model': 'Menü-Muster',
|
||||
'Movies': 'Movies',
|
||||
'My Sites': 'Meine Seiten',
|
||||
'Name': 'Nombre',
|
||||
'New %(entity)s': 'New %(entity)s',
|
||||
'New password': 'Contrasenya nova',
|
||||
'New Record': 'Neuer Eintrag',
|
||||
'new record inserted': 'Neuer Eintrag hinzugefügt',
|
||||
'New Search': 'New Search',
|
||||
'next %s rows': 'nächste %s Reihen',
|
||||
'No databases in this application': 'Keine Datenbank in dieser Anwendung',
|
||||
'No records found': 'No records found',
|
||||
'Not Authorized': 'Zugriff verweigert',
|
||||
'not in': 'not in',
|
||||
'Number of entries: **%s**': 'Nummer der Einträge: **%s**',
|
||||
'Object or table name': 'Objekt oder Tabellenname',
|
||||
'Old password': 'Altes Passwort',
|
||||
@ -165,10 +207,11 @@
|
||||
'Permissions': 'Erlaubnisse',
|
||||
'please input your password again': 'si us plau, entri un altre cop la seva contrasenya',
|
||||
'Plugins': 'Plugins',
|
||||
'Posts': 'Posts',
|
||||
'Powered by': 'Unterstützt von',
|
||||
'Preface': 'Allgemeines',
|
||||
'previous %s rows': 'vorherige %s Reihen',
|
||||
'Profile': 'Perfil',
|
||||
'Profile': 'Profil',
|
||||
'Profile updated': 'Profil aktualisiert',
|
||||
'pygraphviz library not found': 'pygraphviz Bibliothek wurde nicht gefunden',
|
||||
'Python': 'Python',
|
||||
@ -205,10 +248,15 @@
|
||||
'Rows in Table': 'Tabellenreihen',
|
||||
'Rows selected': 'Reihen ausgewählt',
|
||||
'Save model as...': 'Speichere Vorlage als...',
|
||||
'Search': 'Search',
|
||||
'Services': 'Dienste',
|
||||
'Sign Up': 'Registrieren',
|
||||
'Sign up': 'Registrieren',
|
||||
'Size of cache:': 'Cachegröße:',
|
||||
'Spreadsheet-optimised export of tab-separated content including hidden columns. May be slow': 'Spreadsheet-optimised export of tab-separated content including hidden columns. May be slow',
|
||||
'Spreadsheet-optimised export of tab-separated content, visible columns only. May be slow.': 'Spreadsheet-optimised export of tab-separated content, visible columns only. May be slow.',
|
||||
'Start building a new search': 'Start building a new search',
|
||||
'starts with': 'starts with',
|
||||
'state': 'Status',
|
||||
'Statistics': 'Statistik',
|
||||
'Stylesheet': 'Stylesheet',
|
||||
@ -225,7 +273,10 @@
|
||||
'This email already has an account': 'Zu dieser Email gehört bereits ein Account',
|
||||
'Time in Cache (h:m:s)': 'Zeit im Cache (h:m:s)',
|
||||
'Timestamp': 'Zeitstempel',
|
||||
'Title': 'Title',
|
||||
'Traceback': 'Zurückverfolgen',
|
||||
'TSV (Spreadsheets)': 'TSV (Spreadsheets)',
|
||||
'TSV (Spreadsheets, hidden cols)': 'TSV (Spreadsheets, hidden cols)',
|
||||
'Twitter': 'Twitter',
|
||||
'Two-step Login Authentication Code': 'Zweistufiger Login-Authentifizierungscode',
|
||||
'unable to parse csv file': 'csv Datei konnte nicht geparst werden',
|
||||
@ -244,19 +295,24 @@
|
||||
'User %(id)s Username retrieved': 'Se ha recuperat el nom de usuari del usuari %(id)s',
|
||||
'User %(id)s Verification email sent': 'Benutzer %(id)s Bestätigungs-Email gesendet',
|
||||
'User %(id)s verified registration key': 'Benutzer %(id)s verifizierter Registrierungsschlüssel',
|
||||
'User ID': 'ID de Usuari',
|
||||
'User ID': 'ID des Benutzers',
|
||||
'Username': 'Benutzername',
|
||||
'Username already taken': 'Benutzername schon vergeben',
|
||||
'Username retrieve': 'Recuperar nom de usuari',
|
||||
'Users': 'Benutzer',
|
||||
'Value already in database or empty': 'Value already in database or empty',
|
||||
'Verify Password': 'Verificar Contrasenya',
|
||||
'Videos': 'Videos',
|
||||
'View': 'Ansicht',
|
||||
'View %(entity)s': 'View %(entity)s',
|
||||
'Vtt Url': 'Vtt Url',
|
||||
'Welcome %(username)s! Click on the link %(link)s to verify your email': 'Willkommen %(username)s! Klicken Sie auf den Link %(link)s, um Ihre Email zu bestätigen',
|
||||
'Welcome to web2py!': 'Willkommen bei web2py!',
|
||||
'Which called the function %s located in the file %s': 'Welche die Funktion %s in der Datei %s aufrief',
|
||||
'Wiki Example': 'Wiki Beispiel',
|
||||
'Working...': 'Arbeite...',
|
||||
'XML': 'XML',
|
||||
'XML export of columns shown': 'XML export of columns shown',
|
||||
'You are successfully running web2py': 'web2py wird erfolgreich ausgeführt',
|
||||
'You can modify this application and adapt it to your needs': 'Sie können diese Anwendung verändern und Ihren Bedürfnissen anpassen',
|
||||
'You have been invited to join %(site)s, click %(link)s to complete the process': 'Sie wurden eingeladen,%(site)s beizutreten. Klicken Sie auf %(link)s, um den Vorgang abzuschließen',
|
||||
|
20
models/db.py
20
models/db.py
@ -155,21 +155,11 @@ if configuration.get('scheduler.enabled'):
|
||||
# auth.enable_record_versioning(db)
|
||||
db = DAL("sqlite://storage.sqlite")
|
||||
|
||||
db.define_table('image',
|
||||
db.define_table('media_file',
|
||||
Field('title', unique=True),
|
||||
Field('file', 'upload'),
|
||||
Field('vtt_url'),
|
||||
Field('file', 'upload', autodelete=True),
|
||||
format = '%(title)s')
|
||||
|
||||
db.define_table('post',
|
||||
Field('image_id', 'reference image'),
|
||||
Field('author'),
|
||||
Field('email'),
|
||||
Field('body', 'text'))
|
||||
|
||||
db.image.title.requires = IS_NOT_IN_DB(db, db.image.title)
|
||||
db.post.image_id.requires = IS_IN_DB(db, db.image.id, '%(title)s')
|
||||
db.post.author.requires = IS_NOT_EMPTY()
|
||||
db.post.email.requires = IS_EMAIL()
|
||||
db.post.body.requires = IS_NOT_EMPTY()
|
||||
|
||||
db.post.image_id.writable = db.post.image_id.readable = False
|
||||
auth = Auth(db)
|
||||
auth.define_tables(username=True)
|
||||
|
13
modules/.gitignore
vendored
Normal file
13
modules/.gitignore
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
/_cffi_backend.cpython-36m-x86_64-linux-gnu.so
|
||||
/bin/
|
||||
/cffi-1.14.6.dist-info/
|
||||
/cffi.libs/
|
||||
/cffi/
|
||||
/pycparser-2.20.dist-info/
|
||||
/pycparser/
|
||||
/srt-3.5.0.dist-info/
|
||||
/srt.py
|
||||
/srt_tools/
|
||||
/vosk/
|
||||
/vosk-0.3.31.dist-info/
|
||||
/vosk.libs/
|
Binary file not shown.
50
modules/transcription_tools/__init__.py
Normal file
50
modules/transcription_tools/__init__.py
Normal file
@ -0,0 +1,50 @@
|
||||
from vosk import Model, KaldiRecognizer, SetLogLevel
|
||||
import sys
|
||||
import os
|
||||
import wave
|
||||
import subprocess
|
||||
import srt
|
||||
import json
|
||||
import datetime
|
||||
|
||||
|
||||
def create_vtt():
|
||||
sample_rate = 16000
|
||||
model = Model("applications/transcription/private/model")
|
||||
rec = KaldiRecognizer(model, sample_rate)
|
||||
rec.SetWords(True)
|
||||
|
||||
process = subprocess.Popen(['ffmpeg', '-loglevel', 'quiet', '-i',
|
||||
'/home/mschmidt/Videos/100-Meinungen-Video-erstellen.mp4',
|
||||
'-ar', str(sample_rate) , '-ac', '1', '-f', 's16le', '-'],
|
||||
stdout=subprocess.PIPE)
|
||||
|
||||
WORDS_PER_LINE = 7
|
||||
|
||||
def transcribe():
|
||||
results = []
|
||||
subs = []
|
||||
while True:
|
||||
data = process.stdout.read(4000)
|
||||
if len(data) == 0:
|
||||
break
|
||||
if rec.AcceptWaveform(data):
|
||||
results.append(rec.Result())
|
||||
results.append(rec.FinalResult())
|
||||
|
||||
for i, res in enumerate(results):
|
||||
jres = json.loads(res)
|
||||
if not 'result' in jres:
|
||||
continue
|
||||
words = jres['result']
|
||||
for j in range(0, len(words), WORDS_PER_LINE):
|
||||
line = words[j : j + WORDS_PER_LINE]
|
||||
s = srt.Subtitle(index=len(subs),
|
||||
content=" ".join([l['word'] for l in line]),
|
||||
start=datetime.timedelta(seconds=line[0]['start']),
|
||||
end=datetime.timedelta(seconds=line[-1]['end']))
|
||||
subs.append(s)
|
||||
return subs
|
||||
|
||||
return (srt.compose(transcribe()))
|
||||
|
1
private/.gitignore
vendored
Normal file
1
private/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/model/
|
@ -2,10 +2,10 @@
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h1>Current Images</h1>
|
||||
<h1>Mediendateien</h1>
|
||||
<ul>
|
||||
{{for image in images:}}
|
||||
{{=LI(A(image.title, _href=URL("show", args=image.id)))}}
|
||||
{{for media_file in media_files:}}
|
||||
{{=LI(A(media_file.title, _href=URL("show", args=media_file.id)))}}
|
||||
{{pass}}
|
||||
</ul>
|
||||
</div>
|
||||
|
8
views/default/vtt.html
Normal file
8
views/default/vtt.html
Normal file
@ -0,0 +1,8 @@
|
||||
{{extend 'layout.html'}}
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
|
||||
<p>{{=message}}</p>
|
||||
|
||||
</div>
|
||||
</div>
|
Loading…
Reference in New Issue
Block a user