Compare commits
No commits in common. "wip/thunfisch" and "main" have entirely different histories.
wip/thunfi
...
main
|
@ -1,4 +1,4 @@
|
||||||
version: "2.4"
|
version: '2.4'
|
||||||
|
|
||||||
services:
|
services:
|
||||||
app:
|
app:
|
||||||
|
|
|
@ -1,38 +1,23 @@
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from guardian.admin import GuardedModelAdmin
|
from guardian.admin import GuardedModelAdmin
|
||||||
from config.models import TranscodingProfile, Stream, Restream, Pull, Recorder, LocalRecordingStorage, S3RecordingStorage, SRSNode, SRSStreamInstance
|
from config.models import Stream, Restream, Pull, SRSNode, SRSStreamInstance
|
||||||
|
|
||||||
@admin.register(LocalRecordingStorage)
|
|
||||||
class LocalRecordingStorageAdmin(GuardedModelAdmin):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@admin.register(S3RecordingStorage)
|
|
||||||
class S3RecordingStorageAdmin(GuardedModelAdmin):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@admin.register(Recorder)
|
|
||||||
class RecorderAdmin(GuardedModelAdmin):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@admin.register(TranscodingProfile)
|
|
||||||
class TranscodingProfileAdmin(GuardedModelAdmin):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@admin.register(Stream)
|
@admin.register(Stream)
|
||||||
class StreamAdmin(GuardedModelAdmin):
|
class StreamAdmin(GuardedModelAdmin):
|
||||||
pass
|
fields = ['stream', 'name', 'publish_counter']
|
||||||
|
|
||||||
@admin.register(Restream)
|
@admin.register(Restream)
|
||||||
class RestreamAdmin(GuardedModelAdmin):
|
class RestreamAdmin(GuardedModelAdmin):
|
||||||
pass
|
fields = ['name', 'active', 'stream', 'format', 'target']
|
||||||
|
|
||||||
@admin.register(Pull)
|
@admin.register(Pull)
|
||||||
class PullAdmin(GuardedModelAdmin):
|
class PullAdmin(GuardedModelAdmin):
|
||||||
pass
|
fields = ['name', 'active', 'stream', 'source']
|
||||||
|
|
||||||
@admin.register(SRSNode)
|
@admin.register(SRSNode)
|
||||||
class SRSNodeAdmin(GuardedModelAdmin):
|
class SRSNodeAdmin(GuardedModelAdmin):
|
||||||
pass
|
fields = ['name', 'api_base', 'rtmp_base', 'active']
|
||||||
|
|
||||||
@admin.register(SRSStreamInstance)
|
@admin.register(SRSStreamInstance)
|
||||||
class SRSStreamInstanceAdmin(GuardedModelAdmin):
|
class SRSStreamInstanceAdmin(GuardedModelAdmin):
|
||||||
|
|
|
@ -57,20 +57,6 @@ class StreamCreate(ModelSchema):
|
||||||
extra = "forbid"
|
extra = "forbid"
|
||||||
|
|
||||||
|
|
||||||
class LocalRecordingStorage(ModelSchema):
|
|
||||||
class Meta:
|
|
||||||
model = models.LocalRecordingStorage
|
|
||||||
fields = "__all__"
|
|
||||||
|
|
||||||
|
|
||||||
class LocalRecordingStoragePatch(ModelSchema):
|
|
||||||
class Meta:
|
|
||||||
model = models.LocalRecordingStorage
|
|
||||||
exclude = ["id"]
|
|
||||||
fields_optional = "__all__"
|
|
||||||
extra = "forbid"
|
|
||||||
|
|
||||||
|
|
||||||
@router.get('/streams', response=List[Stream])
|
@router.get('/streams', response=List[Stream])
|
||||||
def list_streams(request):
|
def list_streams(request):
|
||||||
return get_objects_for_user(request.user, 'view_stream', models.Stream.objects.all())
|
return get_objects_for_user(request.user, 'view_stream', models.Stream.objects.all())
|
||||||
|
@ -185,9 +171,9 @@ def create_pull(request, payload: Pull):
|
||||||
raise HttpError(401, "unauthorized")
|
raise HttpError(401, "unauthorized")
|
||||||
|
|
||||||
pull = models.Pull.objects.create(**payload.dict())
|
pull = models.Pull.objects.create(**payload.dict())
|
||||||
assign_perm( 'view_pull', request.user, pull)
|
assign_perm( 'view_pull', request.user, Pull)
|
||||||
assign_perm('change_pull', request.user, pull)
|
assign_perm('change_pull', request.user, Pull)
|
||||||
assign_perm('delete_pull', request.user, pull)
|
assign_perm('delete_pull', request.user, Pull)
|
||||||
return pull
|
return pull
|
||||||
|
|
||||||
|
|
||||||
|
@ -228,44 +214,3 @@ def delete_pull(request, id: int):
|
||||||
raise HttpError(401, "unauthorized")
|
raise HttpError(401, "unauthorized")
|
||||||
|
|
||||||
pull.delete()
|
pull.delete()
|
||||||
|
|
||||||
@router.get('/recording/storage/local', response=List[LocalRecordingStorage])
|
|
||||||
def list_local_recording_storage(request):
|
|
||||||
return get_objects_for_user(request.user, 'view_localrecordingstorage', models.LocalRecordingStorage.objects.all())
|
|
||||||
|
|
||||||
@router.get('/recording/storage/local/{id}', response=LocalRecordingStorage)
|
|
||||||
def get_local_recording_storage(request, id: int):
|
|
||||||
obj = get_object_or_404(models.LocalRecordingStorage, id=id)
|
|
||||||
|
|
||||||
if not request.user.has_perm('view_localrecordingstorage', obj):
|
|
||||||
raise HttpError(401, "unauthorized")
|
|
||||||
|
|
||||||
return obj
|
|
||||||
|
|
||||||
@router.post('/recording/storage/local', response=LocalRecordingStorage)
|
|
||||||
def create_local_recording_storage(request, payload: LocalRecordingStorage):
|
|
||||||
obj = models.LocalRecordingStorage.objects.create(**payload.dict())
|
|
||||||
|
|
||||||
assign_perm( 'view_localrecordingstorage', request.user, obj)
|
|
||||||
assign_perm('change_localrecordingstorage', request.user, obj)
|
|
||||||
assign_perm('delete_localrecordingstorage', request.user, obj)
|
|
||||||
return obj
|
|
||||||
|
|
||||||
@router.patch('/recording/storage/local/{id}', response=LocalRecordingStorage)
|
|
||||||
def patch_local_recording_storage(request, id: int, payload: LocalRecordingStoragePatch):
|
|
||||||
obj = get_object_or_404(models.LocalRecordingStorage, id=id)
|
|
||||||
|
|
||||||
if not request.user.has_perm('change_localrecordingstorage', obj):
|
|
||||||
raise HttpError(401, "unauthorized")
|
|
||||||
|
|
||||||
for key, value in payload.dict(exclude_unset=True).items():
|
|
||||||
setattr(obj, key, value)
|
|
||||||
obj.save()
|
|
||||||
return obj
|
|
||||||
|
|
||||||
@router.delete('/recording/storage/local/{id}', response=None)
|
|
||||||
def delete_local_recording_storage(request, id: int):
|
|
||||||
obj = get_object_or_404(models.LocalRecordingStorage, id=id)
|
|
||||||
if not request.user.has_perm('delete_localrecordingstorage', obj):
|
|
||||||
raise HttpError(401, "unauthorized")
|
|
||||||
obj.delete()
|
|
|
@ -1 +0,0 @@
|
||||||
from . import pull, recorder, restream, stream, transcodingprofile
|
|
|
@ -1,77 +0,0 @@
|
||||||
from ninja import Router, ModelSchema, Schema
|
|
||||||
from ninja.errors import HttpError
|
|
||||||
from config import models
|
|
||||||
from typing import List
|
|
||||||
from guardian.shortcuts import get_objects_for_user, assign_perm
|
|
||||||
from django.shortcuts import get_object_or_404
|
|
||||||
|
|
||||||
router = Router()
|
|
||||||
|
|
||||||
class Pull(ModelSchema):
|
|
||||||
class Meta:
|
|
||||||
model = models.Pull
|
|
||||||
fields = "__all__"
|
|
||||||
|
|
||||||
|
|
||||||
class PullPatch(ModelSchema):
|
|
||||||
class Meta:
|
|
||||||
model = models.Pull
|
|
||||||
exclude = ["id"]
|
|
||||||
fields_optional = "__all__"
|
|
||||||
extra = "forbid"
|
|
||||||
|
|
||||||
|
|
||||||
@router.get('/', response=List[Pull])
|
|
||||||
def list_pulls(request):
|
|
||||||
return get_objects_for_user(request.user, 'view_pull', models.Pull.objects.all())
|
|
||||||
|
|
||||||
|
|
||||||
@router.post('/', response=Pull)
|
|
||||||
def create_pull(request, payload: Pull):
|
|
||||||
if not request.user.has_perm('view_stream', payload.stream):
|
|
||||||
raise HttpError(401, "unauthorized")
|
|
||||||
|
|
||||||
pull = models.Pull.objects.create(**payload.dict())
|
|
||||||
assign_perm( 'view_pull', request.user, pull)
|
|
||||||
assign_perm('change_pull', request.user, pull)
|
|
||||||
assign_perm('delete_pull', request.user, pull)
|
|
||||||
return pull
|
|
||||||
|
|
||||||
|
|
||||||
@router.get('/{id}', response=Pull)
|
|
||||||
def get_pull(request, id: int):
|
|
||||||
pull = get_object_or_404(models.Pull, id=id)
|
|
||||||
|
|
||||||
if not request.user.has_perm('view_pull', pull):
|
|
||||||
raise HttpError(401, "unauthorized")
|
|
||||||
|
|
||||||
return pull
|
|
||||||
|
|
||||||
|
|
||||||
@router.patch('/{id}', response=Pull)
|
|
||||||
def patch_pull(request, id: int, payload: PullPatch):
|
|
||||||
pull = get_object_or_404(models.Pull, id=id)
|
|
||||||
|
|
||||||
if not request.user.has_perm('change_pull', pull):
|
|
||||||
raise HttpError(401, "unauthorized")
|
|
||||||
|
|
||||||
if payload.stream:
|
|
||||||
payload.stream = get_object_or_404(models.Stream, id=payload.stream)
|
|
||||||
|
|
||||||
if not request.user.has_perm('view_stream', payload.stream):
|
|
||||||
raise HttpError(401, "unauthorized")
|
|
||||||
|
|
||||||
for key, value in payload.dict(exclude_unset=True).items():
|
|
||||||
setattr(pull, key, value)
|
|
||||||
pull.save()
|
|
||||||
return pull
|
|
||||||
|
|
||||||
|
|
||||||
@router.delete('/{id}', response=None)
|
|
||||||
def delete_pull(request, id: int):
|
|
||||||
pull = get_object_or_404(models.Pull, id=id)
|
|
||||||
|
|
||||||
if not request.user.has_perm('delete_pull', pull):
|
|
||||||
raise HttpError(401, "unauthorized")
|
|
||||||
|
|
||||||
pull.delete()
|
|
|
@ -1,65 +0,0 @@
|
||||||
|
|
||||||
from ninja import Router, ModelSchema, Schema
|
|
||||||
from ninja.errors import HttpError
|
|
||||||
from config import models
|
|
||||||
from typing import List
|
|
||||||
from guardian.shortcuts import get_objects_for_user, assign_perm
|
|
||||||
from django.shortcuts import get_object_or_404
|
|
||||||
|
|
||||||
router = Router()
|
|
||||||
|
|
||||||
|
|
||||||
class LocalRecordingStorage(ModelSchema):
|
|
||||||
class Meta:
|
|
||||||
model = models.LocalRecordingStorage
|
|
||||||
fields = "__all__"
|
|
||||||
|
|
||||||
|
|
||||||
class LocalRecordingStoragePatch(ModelSchema):
|
|
||||||
class Meta:
|
|
||||||
model = models.LocalRecordingStorage
|
|
||||||
exclude = ["id"]
|
|
||||||
fields_optional = "__all__"
|
|
||||||
extra = "forbid"
|
|
||||||
|
|
||||||
|
|
||||||
@router.get('/local', response=List[LocalRecordingStorage])
|
|
||||||
def list_local_recording_storage(request):
|
|
||||||
return get_objects_for_user(request.user, 'view_localrecordingstorage', models.LocalRecordingStorage.objects.all())
|
|
||||||
|
|
||||||
@router.get('/local/{id}', response=LocalRecordingStorage)
|
|
||||||
def get_local_recording_storage(request, id: int):
|
|
||||||
obj = get_object_or_404(models.LocalRecordingStorage, id=id)
|
|
||||||
|
|
||||||
if not request.user.has_perm('view_localrecordingstorage', obj):
|
|
||||||
raise HttpError(401, "unauthorized")
|
|
||||||
|
|
||||||
return obj
|
|
||||||
|
|
||||||
@router.post('/local', response=LocalRecordingStorage)
|
|
||||||
def create_local_recording_storage(request, payload: LocalRecordingStorage):
|
|
||||||
obj = models.LocalRecordingStorage.objects.create(**payload.dict())
|
|
||||||
|
|
||||||
assign_perm( 'view_localrecordingstorage', request.user, obj)
|
|
||||||
assign_perm('change_localrecordingstorage', request.user, obj)
|
|
||||||
assign_perm('delete_localrecordingstorage', request.user, obj)
|
|
||||||
return obj
|
|
||||||
|
|
||||||
@router.patch('/local/{id}', response=LocalRecordingStorage)
|
|
||||||
def patch_local_recording_storage(request, id: int, payload: LocalRecordingStoragePatch):
|
|
||||||
obj = get_object_or_404(models.LocalRecordingStorage, id=id)
|
|
||||||
|
|
||||||
if not request.user.has_perm('change_localrecordingstorage', obj):
|
|
||||||
raise HttpError(401, "unauthorized")
|
|
||||||
|
|
||||||
for key, value in payload.dict(exclude_unset=True).items():
|
|
||||||
setattr(obj, key, value)
|
|
||||||
obj.save()
|
|
||||||
return obj
|
|
||||||
|
|
||||||
@router.delete('/local/{id}', response=None)
|
|
||||||
def delete_local_recording_storage(request, id: int):
|
|
||||||
obj = get_object_or_404(models.LocalRecordingStorage, id=id)
|
|
||||||
if not request.user.has_perm('delete_localrecordingstorage', obj):
|
|
||||||
raise HttpError(401, "unauthorized")
|
|
||||||
obj.delete()
|
|
|
@ -1,78 +0,0 @@
|
||||||
from ninja import Router, ModelSchema, Schema
|
|
||||||
from ninja.errors import HttpError
|
|
||||||
from config import models
|
|
||||||
from typing import List
|
|
||||||
from guardian.shortcuts import get_objects_for_user, assign_perm
|
|
||||||
from django.shortcuts import get_object_or_404
|
|
||||||
|
|
||||||
router = Router()
|
|
||||||
|
|
||||||
|
|
||||||
class Restream(ModelSchema):
|
|
||||||
class Meta:
|
|
||||||
model = models.Restream
|
|
||||||
fields = "__all__"
|
|
||||||
|
|
||||||
|
|
||||||
class RestreamPatch(ModelSchema):
|
|
||||||
class Meta:
|
|
||||||
model = models.Restream
|
|
||||||
exclude = ["id"]
|
|
||||||
fields_optional = "__all__"
|
|
||||||
extra = "forbid"
|
|
||||||
|
|
||||||
|
|
||||||
@router.get('/', response=List[Restream])
|
|
||||||
def list_restreams(request):
|
|
||||||
return get_objects_for_user(request.user, 'view_restream', models.Restream.objects.all())
|
|
||||||
|
|
||||||
|
|
||||||
@router.post('/', response=Restream)
|
|
||||||
def create_restream(request, payload: Restream):
|
|
||||||
if not request.user.has_perm('view_stream', payload.stream):
|
|
||||||
raise HttpError(401, "unauthorized")
|
|
||||||
|
|
||||||
restream = models.Restream.objects.create(**payload.dict())
|
|
||||||
assign_perm('view_restream', request.user, restream)
|
|
||||||
assign_perm('change_restream', request.user, restream)
|
|
||||||
assign_perm('delete_restream', request.user, restream)
|
|
||||||
return restream
|
|
||||||
|
|
||||||
|
|
||||||
@router.get('/{id}', response=Restream)
|
|
||||||
def get_restream(request, id: int):
|
|
||||||
restream = get_object_or_404(models.Restream, id=id)
|
|
||||||
|
|
||||||
if not request.user.has_perm('view_restream', restream):
|
|
||||||
raise HttpError(401, "unauthorized")
|
|
||||||
|
|
||||||
return restream
|
|
||||||
|
|
||||||
|
|
||||||
@router.patch('/{id}', response=Restream)
|
|
||||||
def update_restream(request, id: int, payload: RestreamPatch):
|
|
||||||
restream = get_object_or_404(models.Restream, id=id)
|
|
||||||
|
|
||||||
if not request.user.has_perm('change_restream', restream):
|
|
||||||
raise HttpError(401, "unauthorized")
|
|
||||||
|
|
||||||
if payload.stream:
|
|
||||||
payload.stream = get_object_or_404(models.Stream, id=payload.stream)
|
|
||||||
|
|
||||||
if not request.user.has_perm('view_stream', payload.stream):
|
|
||||||
raise HttpError(401, "unauthorized")
|
|
||||||
|
|
||||||
for key, value in payload.dict(exclude_unset=True).items():
|
|
||||||
setattr(restream, key, value)
|
|
||||||
restream.save()
|
|
||||||
return restream
|
|
||||||
|
|
||||||
|
|
||||||
@router.delete('/{id}', response=None)
|
|
||||||
def delete_restream(request, id: int):
|
|
||||||
restream = get_object_or_404(models.Restream, id=id)
|
|
||||||
|
|
||||||
if not request.user.has_perm('delete_restream', restream):
|
|
||||||
raise HttpError(401, "unauthorized")
|
|
||||||
|
|
||||||
restream.delete()
|
|
|
@ -1,73 +0,0 @@
|
||||||
from ninja import Router, ModelSchema, Schema
|
|
||||||
from ninja.errors import HttpError
|
|
||||||
from config import models
|
|
||||||
from typing import List
|
|
||||||
from guardian.shortcuts import get_objects_for_user, assign_perm
|
|
||||||
from django.shortcuts import get_object_or_404
|
|
||||||
|
|
||||||
router = Router()
|
|
||||||
|
|
||||||
class Stream(ModelSchema):
|
|
||||||
class Meta:
|
|
||||||
model = models.Stream
|
|
||||||
fields = "__all__"
|
|
||||||
|
|
||||||
|
|
||||||
class StreamPatch(ModelSchema):
|
|
||||||
class Meta:
|
|
||||||
model = models.Stream
|
|
||||||
fields = ["name"]
|
|
||||||
fields_optional = "__all__"
|
|
||||||
extra = "forbid"
|
|
||||||
|
|
||||||
|
|
||||||
class StreamCreate(ModelSchema):
|
|
||||||
class Meta:
|
|
||||||
model = models.Stream
|
|
||||||
fields = ["name"]
|
|
||||||
extra = "forbid"
|
|
||||||
|
|
||||||
|
|
||||||
@router.get('/', response=List[Stream])
|
|
||||||
def list_streams(request):
|
|
||||||
return get_objects_for_user(request.user, 'view_stream', models.Stream.objects.all())
|
|
||||||
|
|
||||||
|
|
||||||
@router.post('/', response=Stream)
|
|
||||||
def create_stream(request, payload: StreamCreate):
|
|
||||||
stream = models.Stream.objects.create(**payload.dict())
|
|
||||||
assign_perm('view_stream', request.user, stream)
|
|
||||||
assign_perm('change_stream', request.user, stream)
|
|
||||||
assign_perm('delete_stream', request.user, stream)
|
|
||||||
return stream
|
|
||||||
|
|
||||||
|
|
||||||
@router.get('/{id}', response=Stream)
|
|
||||||
def get_stream(request, id: int):
|
|
||||||
stream = get_object_or_404(models.Stream, id=id)
|
|
||||||
|
|
||||||
if not request.user.has_perm('view_stream', stream):
|
|
||||||
raise HttpError(401, "unauthorized")
|
|
||||||
return stream
|
|
||||||
|
|
||||||
|
|
||||||
@router.patch('/{id}', response=Stream)
|
|
||||||
def update_stream(request, id: int, payload: StreamPatch):
|
|
||||||
stream = get_object_or_404(models.Stream, id=id)
|
|
||||||
|
|
||||||
if not request.user.has_perm('change_stream', stream):
|
|
||||||
raise HttpError(401, "unauthorized")
|
|
||||||
|
|
||||||
stream.name = payload.name
|
|
||||||
stream.save()
|
|
||||||
return stream
|
|
||||||
|
|
||||||
|
|
||||||
@router.delete('/{id}', response=None)
|
|
||||||
def delete_stream(request, id: int):
|
|
||||||
stream = get_object_or_404(models.Stream, id=id)
|
|
||||||
|
|
||||||
if not request.user.has_perm('delete_stream', stream):
|
|
||||||
raise HttpError(401, "unauthorized")
|
|
||||||
|
|
||||||
stream.delete()
|
|
|
@ -1,63 +0,0 @@
|
||||||
|
|
||||||
from ninja import Router, ModelSchema, Schema
|
|
||||||
from ninja.errors import HttpError
|
|
||||||
from config import models
|
|
||||||
from typing import List
|
|
||||||
from guardian.shortcuts import get_objects_for_user, assign_perm
|
|
||||||
from django.shortcuts import get_object_or_404
|
|
||||||
|
|
||||||
router = Router()
|
|
||||||
|
|
||||||
class TranscodingProfile(ModelSchema):
|
|
||||||
class Meta:
|
|
||||||
model = models.TranscodingProfile
|
|
||||||
fields = "__all__"
|
|
||||||
|
|
||||||
class TranscodingProfilePatch(ModelSchema):
|
|
||||||
class Meta:
|
|
||||||
model = models.TranscodingProfile
|
|
||||||
exclude = ["id"]
|
|
||||||
fields_optional = "__all__"
|
|
||||||
extra = "forbid"
|
|
||||||
|
|
||||||
|
|
||||||
@router.get('/', response=List[TranscodingProfile])
|
|
||||||
def list_transcodingprofile(request):
|
|
||||||
return get_objects_for_user(request.user, 'view_transcodingprofile', models.TranscodingProfile.objects.all())
|
|
||||||
|
|
||||||
@router.get('/{id}', response=TranscodingProfile)
|
|
||||||
def get_transcodingprofile(request, id: int):
|
|
||||||
obj = get_object_or_404(models.TranscodingProfile, id=id)
|
|
||||||
|
|
||||||
if not request.user.has_perm('view_transcodingprofile', obj):
|
|
||||||
raise HttpError(401, "unauthorized")
|
|
||||||
|
|
||||||
return obj
|
|
||||||
|
|
||||||
@router.post('/', response=TranscodingProfile)
|
|
||||||
def create_transcodingprofile(request, payload: TranscodingProfilePatch):
|
|
||||||
obj = models.TranscodingProfile.objects.create(**payload.dict())
|
|
||||||
|
|
||||||
assign_perm( 'view_transcodingprofile', request.user, obj)
|
|
||||||
assign_perm('change_transcodingprofile', request.user, obj)
|
|
||||||
assign_perm('delete_transcodingprofile', request.user, obj)
|
|
||||||
return obj
|
|
||||||
|
|
||||||
@router.patch('/{id}', response=TranscodingProfile)
|
|
||||||
def patch_transcodingprofile(request, id: int, payload: TranscodingProfilePatch):
|
|
||||||
obj = get_object_or_404(models.TranscodingProfile, id=id)
|
|
||||||
|
|
||||||
if not request.user.has_perm('change_transcodingprofile', obj):
|
|
||||||
raise HttpError(401, "unauthorized")
|
|
||||||
|
|
||||||
for key, value in payload.dict(exclude_unset=True).items():
|
|
||||||
setattr(obj, key, value)
|
|
||||||
obj.save()
|
|
||||||
return obj
|
|
||||||
|
|
||||||
@router.delete('/{id}', response=None)
|
|
||||||
def delete_transcodingprofile(request, id: int):
|
|
||||||
obj = get_object_or_404(models.TranscodingProfile, id=id)
|
|
||||||
if not request.user.has_perm('delete_transcodingprofile', obj):
|
|
||||||
raise HttpError(401, "unauthorized")
|
|
||||||
obj.delete()
|
|
|
@ -1,59 +0,0 @@
|
||||||
# Generated by Django 5.0.2 on 2024-04-01 18:42
|
|
||||||
|
|
||||||
import django.db.models.deletion
|
|
||||||
import uuid
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('config', '0004_alter_pull_source_alter_restream_target'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='TranscodingProfile',
|
|
||||||
fields=[
|
|
||||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
||||||
('name', models.CharField(help_text='transcodingprofile_name_help', max_length=100)),
|
|
||||||
('video_map_stream', models.PositiveIntegerField(default=0, help_text='transcodingprofile_video_map_stream_help')),
|
|
||||||
('video_codec', models.CharField(choices=[('copy', 'Copy'), ('h264', 'H.264'), ('h265', 'H.265')], help_text='transcodingprofile_video_codec_help', max_length=4)),
|
|
||||||
('video_bitrate', models.PositiveIntegerField(default=6000, help_text='transcodingprofile_video_bitrate_help')),
|
|
||||||
('video_frame_rate', models.PositiveIntegerField(default=30, help_text='transcodingprofile_video_frame_rate_help')),
|
|
||||||
('video_resolution', models.CharField(help_text='transcodingprofile_video_resolution_help', max_length=9)),
|
|
||||||
('video_gop_size', models.PositiveIntegerField(default=60, help_text='transcodingprofile_video_gop_size_help')),
|
|
||||||
('video_pixel_format', models.CharField(choices=[('yuv420', 'YUV420'), ('yuv422', 'YUV422'), ('yuv444', 'YUV444')], help_text='transcodingprofile_video_pixel_format_help', max_length=10)),
|
|
||||||
('video_bitrate_mode', models.CharField(choices=[('cbr', 'CBR'), ('vbr', 'VBR')], help_text='transcodingprofile_video_bitrate_mode_help', max_length=10)),
|
|
||||||
('audio_map_stream', models.PositiveIntegerField(default=0, help_text='transcodingprofile_audio_map_stream_help')),
|
|
||||||
('audio_codec', models.CharField(choices=[('copy', 'Copy'), ('aac', 'AAC')], help_text='transcodingprofile_audio_codec_help', max_length=10)),
|
|
||||||
('audio_bitrate', models.PositiveIntegerField(default=160, help_text='transcodingprofile_audio_bitrate_help')),
|
|
||||||
('audio_channels', models.PositiveIntegerField(default=2, help_text='transcodingprofile_audio_channels_help')),
|
|
||||||
('audio_sample_rate', models.PositiveIntegerField(default=48000, help_text='transcodingprofile_audio_sample_rate_help')),
|
|
||||||
],
|
|
||||||
options={
|
|
||||||
'verbose_name': 'transcodingprofile_verbose_name',
|
|
||||||
'verbose_name_plural': 'transcodingprofile_verbose_name_plural',
|
|
||||||
},
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='stream',
|
|
||||||
name='name',
|
|
||||||
field=models.CharField(help_text='stream_name_help', max_length=100),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='stream',
|
|
||||||
name='stream',
|
|
||||||
field=models.UUIDField(default=uuid.uuid4, help_text='stream_stream_help', unique=True),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='pull',
|
|
||||||
name='transcodingprofile',
|
|
||||||
field=models.ForeignKey(blank=True, help_text='restream_transcodingprofile_help', null=True, on_delete=django.db.models.deletion.PROTECT, to='config.transcodingprofile'),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='restream',
|
|
||||||
name='transcodingprofile',
|
|
||||||
field=models.ForeignKey(blank=True, help_text='restream_transcodingprofile_help', null=True, on_delete=django.db.models.deletion.PROTECT, to='config.transcodingprofile'),
|
|
||||||
),
|
|
||||||
]
|
|
|
@ -1,53 +0,0 @@
|
||||||
# Generated by Django 5.0.2 on 2024-04-13 08:52
|
|
||||||
|
|
||||||
import django.db.models.deletion
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('config', '0005_transcodingprofile_alter_stream_name_and_more'),
|
|
||||||
('contenttypes', '0002_remove_content_type_name'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='LocalRecordingStorage',
|
|
||||||
fields=[
|
|
||||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
||||||
('name', models.CharField(help_text='recordingstorage_name_help', max_length=100)),
|
|
||||||
('path', models.CharField(help_text='localrecordingstorage_path_help', max_length=500)),
|
|
||||||
],
|
|
||||||
options={
|
|
||||||
'verbose_name': 'localrecordingstorage_verbose_name',
|
|
||||||
'verbose_name_plural': 'localrecordingstorage_verbose_name_plural',
|
|
||||||
},
|
|
||||||
),
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='S3RecordingStorage',
|
|
||||||
fields=[
|
|
||||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
||||||
('name', models.CharField(help_text='recordingstorage_name_help', max_length=100)),
|
|
||||||
('bucket', models.CharField(help_text='s3recordingstorage_bucket_help', max_length=100)),
|
|
||||||
('access_key', models.CharField(help_text='s3recordingstorage_access_key_help', max_length=100)),
|
|
||||||
('secret_key', models.CharField(help_text='s3recordingstorage_secret_key_help', max_length=100)),
|
|
||||||
('region', models.CharField(help_text='s3recordingstorage_region_help', max_length=100)),
|
|
||||||
],
|
|
||||||
options={
|
|
||||||
'verbose_name': 's3recordingstorage_verbose_name',
|
|
||||||
'verbose_name_plural': 's3recordingstorage_verbose_name_plural',
|
|
||||||
},
|
|
||||||
),
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='Recorder',
|
|
||||||
fields=[
|
|
||||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
||||||
('name', models.CharField(help_text='recorder_name_help', max_length=100)),
|
|
||||||
('active', models.BooleanField(help_text='recorder_activate_help')),
|
|
||||||
('storage_config_id', models.PositiveIntegerField()),
|
|
||||||
('storage_type', models.ForeignKey(limit_choices_to=models.Q(models.Q(('app_label', 'config'), ('model', 'LocalRecordingStorage')), models.Q(('app_label', 'app'), ('model', 'S3RecordingStorage')), _connector='OR'), on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype')),
|
|
||||||
('stream', models.ForeignKey(help_text='recorder_stream_help', on_delete=django.db.models.deletion.CASCADE, to='config.stream')),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
]
|
|
|
@ -1,9 +1,6 @@
|
||||||
import json
|
import json
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
|
|
||||||
from django.contrib.contenttypes.fields import GenericForeignKey
|
|
||||||
from django.contrib.contenttypes.models import ContentType
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
@ -13,70 +10,6 @@ from portier.common import handlers
|
||||||
from config import signals_shared
|
from config import signals_shared
|
||||||
from config.util import validate_stream_url
|
from config.util import validate_stream_url
|
||||||
|
|
||||||
class TranscodingProfile(models.Model):
|
|
||||||
VIDEO_CODECS = (
|
|
||||||
('copy', 'Copy'),
|
|
||||||
('h264', 'H.264'),
|
|
||||||
('h265', 'H.265'),
|
|
||||||
)
|
|
||||||
AUDIO_CODECS = (
|
|
||||||
('copy', 'Copy'),
|
|
||||||
('aac', 'AAC'),
|
|
||||||
)
|
|
||||||
VIDEO_PIXEL_FORMATS = (
|
|
||||||
('yuv420', 'YUV420'),
|
|
||||||
('yuv422', 'YUV422'),
|
|
||||||
('yuv444', 'YUV444'),
|
|
||||||
)
|
|
||||||
VIDEO_BITRATE_MODES = (
|
|
||||||
('cbr', 'CBR'),
|
|
||||||
('vbr', 'VBR'),
|
|
||||||
)
|
|
||||||
name = models.CharField(max_length=100, help_text=_('transcodingprofile_name_help'))
|
|
||||||
|
|
||||||
video_map_stream = models.PositiveIntegerField(default=0, help_text=_('transcodingprofile_video_map_stream_help'))
|
|
||||||
video_codec = models.CharField(max_length=4, choices=VIDEO_CODECS, help_text=_('transcodingprofile_video_codec_help'))
|
|
||||||
video_bitrate = models.PositiveIntegerField(default=6000, help_text=_('transcodingprofile_video_bitrate_help'))
|
|
||||||
video_frame_rate = models.PositiveIntegerField(default=30, help_text=_('transcodingprofile_video_frame_rate_help'))
|
|
||||||
video_resolution = models.CharField(max_length=9, help_text=_('transcodingprofile_video_resolution_help'))
|
|
||||||
video_gop_size = models.PositiveIntegerField(default=60, help_text=_('transcodingprofile_video_gop_size_help'))
|
|
||||||
video_pixel_format = models.CharField(max_length=10, choices=VIDEO_PIXEL_FORMATS, help_text=_('transcodingprofile_video_pixel_format_help'))
|
|
||||||
video_bitrate_mode = models.CharField(max_length=10, choices=VIDEO_BITRATE_MODES, help_text=_('transcodingprofile_video_bitrate_mode_help'))
|
|
||||||
|
|
||||||
audio_map_stream = models.PositiveIntegerField(default=0, help_text=_('transcodingprofile_audio_map_stream_help'))
|
|
||||||
audio_codec = models.CharField(max_length=10, choices=AUDIO_CODECS, help_text=_('transcodingprofile_audio_codec_help'))
|
|
||||||
audio_bitrate = models.PositiveIntegerField(default=160, help_text=_('transcodingprofile_audio_bitrate_help'))
|
|
||||||
audio_channels = models.PositiveIntegerField(default=2, help_text=_('transcodingprofile_audio_channels_help'))
|
|
||||||
audio_sample_rate = models.PositiveIntegerField(default=48000, help_text=_('transcodingprofile_audio_sample_rate_help'))
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
verbose_name = _('transcodingprofile_verbose_name')
|
|
||||||
verbose_name_plural = _('transcodingprofile_verbose_name_plural')
|
|
||||||
|
|
||||||
def class_name(self):
|
|
||||||
return _('transcodingprofile_class_name')
|
|
||||||
|
|
||||||
def get_absolute_url(self):
|
|
||||||
return reverse('config:transcodingprofile_detail', kwargs={'pk': self.pk})
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return str(self.name)
|
|
||||||
|
|
||||||
def get_concierge_configuration(self):
|
|
||||||
return {
|
|
||||||
'config_version': 1,
|
|
||||||
'video_map_stream': self.video_map_stream,
|
|
||||||
'video_codec': self.video_codec,
|
|
||||||
'video_bitrate': self.video_bitrate,
|
|
||||||
'video_frame_rate': self.video_frame_rate,
|
|
||||||
'video_resolution': self.video_resolution,
|
|
||||||
'audio_map_stream': self.audio_map_stream,
|
|
||||||
'audio_codec': self.audio_codec,
|
|
||||||
'audio_bitrate': self.audio_bitrate,
|
|
||||||
'audio_channels': self.audio_channels,
|
|
||||||
'audio_sample_rate': self.audio_sample_rate,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class Stream(models.Model):
|
class Stream(models.Model):
|
||||||
stream = models.UUIDField(unique=True, default=uuid.uuid4, help_text=_('stream_stream_help'))
|
stream = models.UUIDField(unique=True, default=uuid.uuid4, help_text=_('stream_stream_help'))
|
||||||
|
@ -112,6 +45,9 @@ class Stream(models.Model):
|
||||||
return str(self.name)
|
return str(self.name)
|
||||||
|
|
||||||
|
|
||||||
|
pre_delete.connect(handlers.remove_obj_perms_connected_with_user, sender=Stream)
|
||||||
|
|
||||||
|
|
||||||
class SRSNode(models.Model):
|
class SRSNode(models.Model):
|
||||||
name = models.CharField(max_length=100, help_text=_('srsnode_name_help'))
|
name = models.CharField(max_length=100, help_text=_('srsnode_name_help'))
|
||||||
api_base = models.CharField(max_length=256, help_text=_('srsnode_api_base_help'))
|
api_base = models.CharField(max_length=256, help_text=_('srsnode_api_base_help'))
|
||||||
|
@ -145,7 +81,6 @@ class Pull(models.Model):
|
||||||
source = models.CharField(max_length=500, validators=[validate_stream_url], help_text=_('pull_source_help'))
|
source = models.CharField(max_length=500, validators=[validate_stream_url], help_text=_('pull_source_help'))
|
||||||
active = models.BooleanField(help_text=_('pull_activate_help'))
|
active = models.BooleanField(help_text=_('pull_activate_help'))
|
||||||
name = models.CharField(max_length=100, help_text=_('pull_name_help'))
|
name = models.CharField(max_length=100, help_text=_('pull_name_help'))
|
||||||
transcodingprofile = models.ForeignKey(TranscodingProfile, null=True, blank=True, on_delete=models.PROTECT, help_text=_('restream_transcodingprofile_help'))
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _('pull_verbose_name')
|
verbose_name = _('pull_verbose_name')
|
||||||
|
@ -181,16 +116,17 @@ class Pull(models.Model):
|
||||||
node = SRSNode.objects.filter(active=True).order_by('?').first()
|
node = SRSNode.objects.filter(active=True).order_by('?').first()
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'config_version': 1,
|
|
||||||
"type": "pull",
|
"type": "pull",
|
||||||
"active": self.active,
|
"active": self.active,
|
||||||
"name": self.name,
|
"name": self.name,
|
||||||
"source": self.source,
|
"source": self.source,
|
||||||
"target": f"{node.rtmp_base}/{settings.GLOBAL_STREAM_NAMESPACE}/{self.stream.stream}",
|
"target": f"{node.rtmp_base}/{settings.GLOBAL_STREAM_NAMESPACE}/{self.stream.stream}",
|
||||||
'transcoding_profile': self.transcodingprofile.get_concierge_configuration(),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pre_delete.connect(handlers.remove_obj_perms_connected_with_user, sender=Pull)
|
||||||
|
|
||||||
|
|
||||||
class Restream(models.Model):
|
class Restream(models.Model):
|
||||||
FORMATS = (
|
FORMATS = (
|
||||||
('flv', 'flv (RTMP)'),
|
('flv', 'flv (RTMP)'),
|
||||||
|
@ -201,7 +137,6 @@ class Restream(models.Model):
|
||||||
name = models.CharField(max_length=100, help_text=_('restream_name_help'))
|
name = models.CharField(max_length=100, help_text=_('restream_name_help'))
|
||||||
active = models.BooleanField(help_text=_('restream_activate_help'))
|
active = models.BooleanField(help_text=_('restream_activate_help'))
|
||||||
format = models.CharField(max_length=6, choices=FORMATS, default='flv', help_text=_('restream_format_help'))
|
format = models.CharField(max_length=6, choices=FORMATS, default='flv', help_text=_('restream_format_help'))
|
||||||
transcodingprofile = models.ForeignKey(TranscodingProfile, null=True, blank=True, on_delete=models.PROTECT, help_text=_('restream_transcodingprofile_help'))
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _('restream_verbose_name')
|
verbose_name = _('restream_verbose_name')
|
||||||
|
@ -241,53 +176,7 @@ class Restream(models.Model):
|
||||||
'stream_source_url': f"{rtmp_base}/{settings.GLOBAL_STREAM_NAMESPACE}/{self.stream.stream}",
|
'stream_source_url': f"{rtmp_base}/{settings.GLOBAL_STREAM_NAMESPACE}/{self.stream.stream}",
|
||||||
'stream_target_url': self.target,
|
'stream_target_url': self.target,
|
||||||
'stream_target_transport': self.format,
|
'stream_target_transport': self.format,
|
||||||
'transcoding_profile': self.transcodingprofile.get_concierge_configuration(),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pre_delete.connect(handlers.remove_obj_perms_connected_with_user, sender=Stream)
|
|
||||||
pre_delete.connect(handlers.remove_obj_perms_connected_with_user, sender=Restream)
|
pre_delete.connect(handlers.remove_obj_perms_connected_with_user, sender=Restream)
|
||||||
pre_delete.connect(handlers.remove_obj_perms_connected_with_user, sender=Pull)
|
|
||||||
|
|
||||||
|
|
||||||
### Recording Storage configurations
|
|
||||||
|
|
||||||
class RecordingStorage(models.Model):
|
|
||||||
name = models.CharField(max_length=100, help_text=_('recordingstorage_name_help'))
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
abstract = True
|
|
||||||
|
|
||||||
|
|
||||||
class LocalRecordingStorage(RecordingStorage):
|
|
||||||
path = models.CharField(max_length=500, help_text=_('localrecordingstorage_path_help'))
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
verbose_name = _('localrecordingstorage_verbose_name')
|
|
||||||
verbose_name_plural = _('localrecordingstorage_verbose_name_plural')
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self.name
|
|
||||||
|
|
||||||
class S3RecordingStorage(RecordingStorage):
|
|
||||||
bucket = models.CharField(max_length=100, help_text=_('s3recordingstorage_bucket_help'))
|
|
||||||
access_key = models.CharField(max_length=100, help_text=_('s3recordingstorage_access_key_help'))
|
|
||||||
secret_key = models.CharField(max_length=100, help_text=_('s3recordingstorage_secret_key_help'))
|
|
||||||
region = models.CharField(max_length=100, help_text=_('s3recordingstorage_region_help'))
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
verbose_name = _('s3recordingstorage_verbose_name')
|
|
||||||
verbose_name_plural = _('s3recordingstorage_verbose_name_plural')
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self.name
|
|
||||||
|
|
||||||
|
|
||||||
class Recorder(models.Model):
|
|
||||||
storage_type_models = models.Q(app_label = 'config', model = 'LocalRecordingStorage') | models.Q(app_label = 'app', model = 'S3RecordingStorage')
|
|
||||||
|
|
||||||
stream = models.ForeignKey(Stream, on_delete=models.CASCADE, help_text=_('recorder_stream_help'))
|
|
||||||
name = models.CharField(max_length=100, help_text=_('recorder_name_help'))
|
|
||||||
active = models.BooleanField(help_text=_('recorder_activate_help'))
|
|
||||||
storage_type = models.ForeignKey(ContentType, limit_choices_to=storage_type_models, on_delete=models.CASCADE)
|
|
||||||
storage_config_id = models.PositiveIntegerField()
|
|
||||||
storage_config = GenericForeignKey('storage_type', 'storage_config_id')
|
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
{% extends 'base.html' %}
|
|
||||||
{% load i18n %}
|
|
||||||
{% load static %}
|
|
||||||
{% load bootstrap4 %}
|
|
||||||
{% load fontawesome_5 %}
|
|
||||||
|
|
||||||
{% block 'sidenav' %}
|
|
||||||
{% with 'transcodingprofile' as section %}
|
|
||||||
{{ block.super }}
|
|
||||||
{% endwith %}
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block 'content' %}
|
|
||||||
|
|
||||||
<h6>{% trans "confirm_delete_header" %}</h6>
|
|
||||||
<hr class="my-4" />
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm border-right">
|
|
||||||
<form method="post">
|
|
||||||
{% csrf_token %}
|
|
||||||
<p>
|
|
||||||
{% blocktrans with transcodingprofile_config_name=object.name %}
|
|
||||||
are_you_sure_you_want_to_delete_"{{ transcodingprofile_config_name }}"?
|
|
||||||
{% endblocktrans %}
|
|
||||||
</p>
|
|
||||||
{% buttons %}
|
|
||||||
<button type="submit" class="btn btn-danger" value="login">
|
|
||||||
{% fa5_icon 'trash' %} {% trans "delete" %}
|
|
||||||
</button>
|
|
||||||
{% endbuttons %}
|
|
||||||
<input type="hidden" name="next" value="{{ next }}" />
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm"></div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
|
@ -1,121 +0,0 @@
|
||||||
{% extends 'base.html' %}
|
|
||||||
{% load i18n %}
|
|
||||||
{% load static %}
|
|
||||||
{% load bootstrap4 %}
|
|
||||||
{% load fontawesome_5 %}
|
|
||||||
{% load guardian_tags %}
|
|
||||||
{% block 'sidenav' %}
|
|
||||||
{% with 'transcodingprofile' as section %} {{ block.super }} {% endwith %}
|
|
||||||
{% endblock %}
|
|
||||||
{% block 'content' %}
|
|
||||||
|
|
||||||
<div class="row justify-content-between">
|
|
||||||
<div class="col">
|
|
||||||
<h6>{% trans "transcodingprofile_configuration_details_header" %}</h6>
|
|
||||||
</div>
|
|
||||||
{% get_obj_perms user for object as "obj_perms" %}
|
|
||||||
<div class="col-auto">
|
|
||||||
{% if "change_transcodingprofile" in obj_perms %}
|
|
||||||
<a
|
|
||||||
href="{% url 'config:transcodingprofile_change' pk=object.pk %}"
|
|
||||||
type="button"
|
|
||||||
class="btn btn-sm btn-outline-primary"
|
|
||||||
>{% fa5_icon 'edit' %} {% trans 'change' %}</a
|
|
||||||
>
|
|
||||||
{% endif %} {% if "delete_transcodingprofile" in obj_perms %}
|
|
||||||
<a
|
|
||||||
href="{% url 'config:transcodingprofile_delete' pk=object.pk %}"
|
|
||||||
type="button"
|
|
||||||
class="btn btn-sm btn-outline-danger"
|
|
||||||
>{% fa5_icon 'trash' %} {% trans 'delete' %}</a
|
|
||||||
>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<hr class="my-4" />
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm border-right">
|
|
||||||
<h5>Video</h5>
|
|
||||||
<dl class="row">
|
|
||||||
<dt class="col-sm-3">
|
|
||||||
{% trans "transcodingprofile_video_map_stream" %}
|
|
||||||
</dt>
|
|
||||||
<dd class="col-sm-9">{{ object.video_map_stream }}</dd>
|
|
||||||
<dt class="col-sm-3">
|
|
||||||
{% trans "transcodingprofile_video_codec" %}
|
|
||||||
</dt>
|
|
||||||
<dd class="col-sm-9">{{ object.get_video_codec_display }}</dd>
|
|
||||||
<dt class="col-sm-3">
|
|
||||||
{% trans "transcodingprofile_video_bitrate" %}
|
|
||||||
</dt>
|
|
||||||
<dd class="col-sm-9">{{ object.video_bitrate }} kbps</dd>
|
|
||||||
<dt class="col-sm-3">
|
|
||||||
{% trans "transcodingprofile_video_bitrate_mode" %}
|
|
||||||
</dt>
|
|
||||||
<dd class="col-sm-9">{{ object.get_video_bitrate_mode_display }}</dd>
|
|
||||||
<dt class="col-sm-3">
|
|
||||||
{% trans "transcodingprofile_video_gop_size" %}
|
|
||||||
</dt>
|
|
||||||
<dd class="col-sm-9">{{ object.video_gop_size }}</dd>
|
|
||||||
<dt class="col-sm-3">
|
|
||||||
{% trans "transcodingprofile_video_pixel_format" %}
|
|
||||||
</dt>
|
|
||||||
<dd class="col-sm-9">{{ object.get_video_pixel_format_display }}</dd>
|
|
||||||
<dt class="col-sm-3">
|
|
||||||
{% trans "transcodingprofile_video_resolution" %}
|
|
||||||
</dt>
|
|
||||||
<dd class="col-sm-9">{{ object.video_resolution }}</dd>
|
|
||||||
<dt class="col-sm-3">
|
|
||||||
{% trans "transcodingprofile_video_frame_rate" %}
|
|
||||||
</dt>
|
|
||||||
<dd class="col-sm-9">{{ object.video_frame_rate }}</dd>
|
|
||||||
</dl>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm">
|
|
||||||
<h5>Audio</h5>
|
|
||||||
<dl class="row">
|
|
||||||
<dt class="col-sm-3">
|
|
||||||
{% trans "transcodingprofile_audio_map_stream" %}
|
|
||||||
</dt>
|
|
||||||
<dd class="col-sm-9">{{ object.audio_map_stream }}</dd>
|
|
||||||
<dt class="col-sm-3">
|
|
||||||
{% trans "transcodingprofile_audio_codec" %}
|
|
||||||
</dt>
|
|
||||||
<dd class="col-sm-9">{{ object.get_audio_codec_display }}</dd>
|
|
||||||
<dt class="col-sm-3">
|
|
||||||
{% trans "transcodingprofile_audio_bitrate" %}
|
|
||||||
</dt>
|
|
||||||
<dd class="col-sm-9">{{ object.audio_bitrate }} kbps</dd>
|
|
||||||
<dt class="col-sm-3">
|
|
||||||
{% trans "transcodingprofile_audio_channels" %}
|
|
||||||
</dt>
|
|
||||||
<dd class="col-sm-9">{{ object.audio_channels }}</dd>
|
|
||||||
<dt class="col-sm-3">
|
|
||||||
{% trans "transcodingprofile_audio_sample_rate" %}
|
|
||||||
</dt>
|
|
||||||
<dd class="col-sm-9">{{ object.audio_sample_rate }}</dd>
|
|
||||||
</dl>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<script>
|
|
||||||
$(function () {
|
|
||||||
$('[data-toggle="popover"]').popover();
|
|
||||||
});
|
|
||||||
$(function () {
|
|
||||||
$("#show_hide_source_url a").on("click", function (event) {
|
|
||||||
event.preventDefault();
|
|
||||||
if ($("#show_hide_source_url input").attr("type") == "text") {
|
|
||||||
$("#show_hide_source_url input").attr("type", "password");
|
|
||||||
$("#show_hide_source_url i").addClass("fa-eye-slash");
|
|
||||||
$("#show_hide_source_url i").removeClass("fa-eye");
|
|
||||||
} else if (
|
|
||||||
$("#show_hide_source_url input").attr("type") == "password"
|
|
||||||
) {
|
|
||||||
$("#show_hide_source_url input").attr("type", "text");
|
|
||||||
$("#show_hide_source_url i").removeClass("fa-eye-slash");
|
|
||||||
$("#show_hide_source_url i").addClass("fa-eye");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
|
|
@ -1,72 +0,0 @@
|
||||||
{% extends 'base.html' %}
|
|
||||||
{% load i18n %}
|
|
||||||
{% load static %}
|
|
||||||
{% load bootstrap4 %}
|
|
||||||
{% load fontawesome_5 %}
|
|
||||||
{% block 'sidenav' %}
|
|
||||||
{% with 'transcodingprofile' as section %}
|
|
||||||
{{ block.super }}
|
|
||||||
{% endwith %}
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block 'content' %}
|
|
||||||
|
|
||||||
<div class="row justify-content-between">
|
|
||||||
<div class="col">
|
|
||||||
<h6>{% trans "transcodingprofile_configuration_header" %}</h6>
|
|
||||||
</div>
|
|
||||||
<div class="col-auto">
|
|
||||||
<div class="btn-toolbar" role="toolbar">
|
|
||||||
<div class="btn-group" role="group">
|
|
||||||
<a
|
|
||||||
href="{% url 'config:transcodingprofile_create' %}"
|
|
||||||
type="button"
|
|
||||||
class="btn btn-sm btn-outline-primary"
|
|
||||||
>{% fa5_icon 'plus' %} {% trans "create" %}</a
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<hr class="my-4" />
|
|
||||||
<div id="app">
|
|
||||||
<div v-if="isLoading">
|
|
||||||
<div class="my-4 text-center">
|
|
||||||
<div class="spinner-border" role="status">
|
|
||||||
<span class="sr-only">{% trans "loading..." %}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<table v-else class="table">
|
|
||||||
<thead class="thead-light">
|
|
||||||
<tr>
|
|
||||||
<th scope="col">{% trans "name" %}</th>
|
|
||||||
<th scope="col" class="text-right">{% trans "actions" %}</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr v-for="cfg in cfgs">
|
|
||||||
<th scope="row">{% verbatim %}{{cfg.name}}{% endverbatim %}</th>
|
|
||||||
<td align="right">
|
|
||||||
<a
|
|
||||||
v-bind:href="detailLink(cfg.id)"
|
|
||||||
type="button"
|
|
||||||
class="btn btn-sm btn-outline-primary"
|
|
||||||
>{% trans "details" %}</a
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
v-bind:href="deleteLink(cfg.id)"
|
|
||||||
type="button"
|
|
||||||
class="btn btn-sm btn-outline-danger"
|
|
||||||
>{% fa5_icon 'trash' %}</a
|
|
||||||
>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script src="{% static 'js/vue.min.js' %}"></script>
|
|
||||||
<script src="{% static 'js/axios.min.js' %}"></script>
|
|
||||||
<script src="{% static 'js/transcodingprofile-list.js' %}"></script>
|
|
||||||
{% endblock %}
|
|
|
@ -1,29 +0,0 @@
|
||||||
{% extends 'base.html' %}
|
|
||||||
{% load i18n %}
|
|
||||||
{% load bootstrap4 %}
|
|
||||||
|
|
||||||
{% block 'sidenav' %}
|
|
||||||
{% with 'transcodingprofile' as section %}
|
|
||||||
{{ block.super }}
|
|
||||||
{% endwith %}
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block 'content' %}
|
|
||||||
<h6>{% trans "update_transcodingprofile_configuration_header" %}</h6>
|
|
||||||
<hr class="my-4">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col">
|
|
||||||
{% trans "transcodingprofile_configuration_text_html" %}
|
|
||||||
<form method="post">
|
|
||||||
{% csrf_token %}
|
|
||||||
{% bootstrap_form form %}
|
|
||||||
{% buttons %}
|
|
||||||
<button type="submit" class="btn btn-primary" value="login">
|
|
||||||
{% trans "submit" %}
|
|
||||||
</button>
|
|
||||||
{% endbuttons %}
|
|
||||||
<input type="hidden" name="next" value="{{ next }}">
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
|
@ -1,5 +1,5 @@
|
||||||
from django.urls import path
|
from django.urls import path
|
||||||
from config.views import restream, stream, pull, transcodingprofile
|
from config.views import restream, stream, pull
|
||||||
from config.views.srs import callback_srs
|
from config.views.srs import callback_srs
|
||||||
|
|
||||||
app_name = 'config'
|
app_name = 'config'
|
||||||
|
@ -21,9 +21,4 @@ urlpatterns = [
|
||||||
path('pull/<int:pk>/change', pull.PullUpdate.as_view(), name='pull_change'),
|
path('pull/<int:pk>/change', pull.PullUpdate.as_view(), name='pull_change'),
|
||||||
path('pull/<int:pk>/delete', pull.PullDelete.as_view(), name='pull_delete'),
|
path('pull/<int:pk>/delete', pull.PullDelete.as_view(), name='pull_delete'),
|
||||||
path('pull/create', pull.PullCreate.as_view(), name='pull_create'),
|
path('pull/create', pull.PullCreate.as_view(), name='pull_create'),
|
||||||
path('transcodingprofile/', transcodingprofile.TranscodingProfileList.as_view(), name='transcodingprofile_list'),
|
|
||||||
path('transcodingprofile/<int:pk>/', transcodingprofile.TranscodingProfileDetail.as_view(), name='transcodingprofile_detail'),
|
|
||||||
path('transcodingprofile/<int:pk>/change', transcodingprofile.TranscodingProfileUpdate.as_view(), name='transcodingprofile_change'),
|
|
||||||
path('transcodingprofile/<int:pk>/delete', transcodingprofile.TranscodingProfileDelete.as_view(), name='transcodingprofile_delete'),
|
|
||||||
path('transcodingprofile/create', transcodingprofile.TranscodingProfileCreate.as_view(), name='transcodingprofile_create'),
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,86 +0,0 @@
|
||||||
import logging
|
|
||||||
|
|
||||||
from django.urls import reverse_lazy
|
|
||||||
from django.contrib.auth.decorators import login_required
|
|
||||||
from django.utils.decorators import method_decorator
|
|
||||||
from django.views.decorators.csrf import ensure_csrf_cookie
|
|
||||||
from django.views.generic import ListView, DetailView, CreateView, DeleteView, UpdateView
|
|
||||||
from guardian.decorators import permission_required_or_403
|
|
||||||
from guardian.shortcuts import assign_perm
|
|
||||||
|
|
||||||
from config import models, forms
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@method_decorator(login_required, name='dispatch')
|
|
||||||
@method_decorator(permission_required_or_403('config.add_restream'),
|
|
||||||
name='dispatch')
|
|
||||||
@method_decorator(ensure_csrf_cookie, name='dispatch')
|
|
||||||
class TranscodingProfileList(ListView):
|
|
||||||
model = models.TranscodingProfile
|
|
||||||
|
|
||||||
|
|
||||||
@method_decorator(login_required, name='dispatch')
|
|
||||||
@method_decorator(permission_required_or_403('config.view_transcodingprofile',
|
|
||||||
(models.TranscodingProfile, 'pk', 'pk')),
|
|
||||||
name='dispatch')
|
|
||||||
class TranscodingProfileDetail(DetailView):
|
|
||||||
model = models.TranscodingProfile
|
|
||||||
|
|
||||||
|
|
||||||
@method_decorator(login_required, name='dispatch')
|
|
||||||
@method_decorator(permission_required_or_403('config.change_transcodingprofile',
|
|
||||||
(models.TranscodingProfile, 'pk', 'pk')),
|
|
||||||
name='dispatch')
|
|
||||||
class TranscodingProfileUpdate(UpdateView):
|
|
||||||
model = models.TranscodingProfile
|
|
||||||
template_name_suffix = '_update_form'
|
|
||||||
|
|
||||||
fields = [
|
|
||||||
'name',
|
|
||||||
'video_map_stream',
|
|
||||||
'video_codec',
|
|
||||||
'video_bitrate',
|
|
||||||
'video_frame_rate',
|
|
||||||
'video_resolution',
|
|
||||||
'video_gop_size',
|
|
||||||
'video_pixel_format',
|
|
||||||
'audio_map_stream',
|
|
||||||
'audio_codec',
|
|
||||||
'audio_bitrate',
|
|
||||||
'audio_sample_rate',
|
|
||||||
'audio_channels',
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
@method_decorator(login_required, name='dispatch')
|
|
||||||
@method_decorator(permission_required_or_403('config.add_transcodingprofile'),
|
|
||||||
name='dispatch')
|
|
||||||
class TranscodingProfileCreate(CreateView):
|
|
||||||
model = models.TranscodingProfile
|
|
||||||
|
|
||||||
def get_form_kwargs(self):
|
|
||||||
kwargs = super().get_form_kwargs()
|
|
||||||
kwargs['user'] = self.request.user
|
|
||||||
return kwargs
|
|
||||||
|
|
||||||
def form_valid(self, form):
|
|
||||||
valid = super().form_valid(form)
|
|
||||||
if valid:
|
|
||||||
user = self.request.user
|
|
||||||
assign_perm('view_transcodingprofile', user, self.object)
|
|
||||||
assign_perm('change_transcodingprofile', user, self.object)
|
|
||||||
assign_perm('delete_transcodingprofile', user, self.object)
|
|
||||||
return valid
|
|
||||||
|
|
||||||
|
|
||||||
@method_decorator(login_required, name='dispatch')
|
|
||||||
@method_decorator(permission_required_or_403('config.delete_transcodingprofile',
|
|
||||||
(models.TranscodingProfile, 'pk', 'pk')),
|
|
||||||
name='dispatch')
|
|
||||||
class TranscodingProfileDelete(DeleteView):
|
|
||||||
model = models.TranscodingProfile
|
|
||||||
success_url = reverse_lazy('config:transcodingprofile_list')
|
|
|
@ -5,8 +5,7 @@ from django.conf import settings
|
||||||
|
|
||||||
PERMISSIONS = [
|
PERMISSIONS = [
|
||||||
'add_stream',
|
'add_stream',
|
||||||
'add_restream',
|
'add_restream'
|
||||||
'add_pull',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,339 @@
|
||||||
|
# Copyright (C) Chaoswest TV
|
||||||
|
# This file is distributed under the same license as the PACKAGE package.
|
||||||
|
# Jan Koppe <post@jankoppe.de>, 2020.
|
||||||
|
#
|
||||||
|
#, fuzzy
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: portier 0.6.0\n"
|
||||||
|
"Report-Msgid-Bugs-To: \n"
|
||||||
|
"POT-Creation-Date: 2024-02-25 20:42+0000\n"
|
||||||
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
|
"Last-Translator: Jan Koppe <post@jankoppe.de>\n"
|
||||||
|
"Language-Team: German <post@chaoswest.tv>\n"
|
||||||
|
"Language: \n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
|
|
||||||
|
#: portier/settings.py:141
|
||||||
|
msgid "German"
|
||||||
|
msgstr "Deutsch"
|
||||||
|
|
||||||
|
#: portier/settings.py:142
|
||||||
|
msgid "English"
|
||||||
|
msgstr "Englisch"
|
||||||
|
|
||||||
|
#: restream/models.py:16
|
||||||
|
msgid "restreamconfig_stream_help"
|
||||||
|
msgstr "Stream der als Quelle für die Weiterleitung verwendet wird"
|
||||||
|
|
||||||
|
#: restream/models.py:17
|
||||||
|
msgid "restreamconfig_target_help"
|
||||||
|
msgstr ""
|
||||||
|
"Ziel URL an die der Stream weitergeleitet wird, inklusive Schema (z.B. "
|
||||||
|
"rtmp://)"
|
||||||
|
|
||||||
|
#: restream/models.py:18
|
||||||
|
msgid "restreamconfig_name_help"
|
||||||
|
msgstr "Name für diese Restream Konfiguration"
|
||||||
|
|
||||||
|
#: restream/models.py:19
|
||||||
|
msgid "restreamconfig_activate_help"
|
||||||
|
msgstr "Nur aktive Konfigurationen werden bei eingehenden Streams ausgeführt"
|
||||||
|
|
||||||
|
#: restream/models.py:20
|
||||||
|
#, fuzzy
|
||||||
|
#| msgid "restreamconfig_target_help"
|
||||||
|
msgid "restreamconfig_format_help"
|
||||||
|
msgstr ""
|
||||||
|
"Ziel URL an die der Stream weitergeleitet wird, inklusive Schema (z.B. "
|
||||||
|
"rtmp://)"
|
||||||
|
|
||||||
|
#: restream/models.py:23
|
||||||
|
msgid "restreamconfig_verbose_name"
|
||||||
|
msgstr "Restream Konfiguration"
|
||||||
|
|
||||||
|
#: restream/models.py:24
|
||||||
|
msgid "restreamconfig_verbose_name_plural"
|
||||||
|
msgstr "Restream Konfigurationen"
|
||||||
|
|
||||||
|
#: restream/models.py:27
|
||||||
|
msgid "restreamconfig_class_name"
|
||||||
|
msgstr "Restream Konfiguration"
|
||||||
|
|
||||||
|
#: restream/templates/restream/restreamconfig_confirm_delete.html:6
|
||||||
|
#: rtmp/templates/rtmp/stream_confirm_delete.html:6
|
||||||
|
msgid "confirm_delete_header"
|
||||||
|
msgstr "Löschen bestätigen"
|
||||||
|
|
||||||
|
#: restream/templates/restream/restreamconfig_confirm_delete.html:12
|
||||||
|
#, python-format
|
||||||
|
msgid "are_you_sure_you_want_to_delete_\"%(restreamconfig_config_name)s\"?"
|
||||||
|
msgstr ""
|
||||||
|
"Bist du sicher, dass du \"%(restreamconfig_config_name)s\" löschen willst?"
|
||||||
|
|
||||||
|
#: restream/templates/restream/restreamconfig_confirm_delete.html:15
|
||||||
|
#: restream/templates/restream/restreamconfig_detail.html:20
|
||||||
|
#: rtmp/templates/rtmp/stream_confirm_delete.html:18
|
||||||
|
#: rtmp/templates/rtmp/stream_detail.html:20
|
||||||
|
msgid "delete"
|
||||||
|
msgstr "Löschen"
|
||||||
|
|
||||||
|
#: restream/templates/restream/restreamconfig_detail.html:12
|
||||||
|
msgid "restreamconfig_configuration_details_header"
|
||||||
|
msgstr "Restream Konfiguration Details"
|
||||||
|
|
||||||
|
#: restream/templates/restream/restreamconfig_detail.html:17
|
||||||
|
#: rtmp/templates/rtmp/stream_detail.html:17
|
||||||
|
msgid "change"
|
||||||
|
msgstr "Ändern"
|
||||||
|
|
||||||
|
#: restream/templates/restream/restreamconfig_detail.html:28
|
||||||
|
#: restream/templates/restream/restreamconfig_list.html:33
|
||||||
|
#: rtmp/templates/rtmp/stream_detail.html:28
|
||||||
|
#: rtmp/templates/rtmp/stream_list.html:33
|
||||||
|
msgid "name"
|
||||||
|
msgstr "Name"
|
||||||
|
|
||||||
|
#: restream/templates/restream/restreamconfig_detail.html:30
|
||||||
|
msgid "stream"
|
||||||
|
msgstr "Stream"
|
||||||
|
|
||||||
|
#: restream/templates/restream/restreamconfig_detail.html:32
|
||||||
|
#: restream/templates/restream/restreamconfig_list.html:34
|
||||||
|
msgid "active"
|
||||||
|
msgstr "Aktiv"
|
||||||
|
|
||||||
|
#: restream/templates/restream/restreamconfig_detail.html:43
|
||||||
|
msgid "configured_target_url"
|
||||||
|
msgstr "Konfigurierte Ziel-URL"
|
||||||
|
|
||||||
|
#: restream/templates/restream/restreamconfig_form.html:5
|
||||||
|
msgid "create_new_restreamconfig_configuration_header"
|
||||||
|
msgstr "Neue Restream Konfiguration erstellen"
|
||||||
|
|
||||||
|
#: restream/templates/restream/restreamconfig_form.html:14
|
||||||
|
#: restream/templates/restream/restreamconfig_update_form.html:14
|
||||||
|
#: rtmp/templates/rtmp/stream_form.html:14
|
||||||
|
#: rtmp/templates/rtmp/stream_update_form.html:14
|
||||||
|
#: templates/registration/password_change_form.html:14
|
||||||
|
#: templates/registration/password_reset_form.html:14
|
||||||
|
msgid "submit"
|
||||||
|
msgstr "Abschicken"
|
||||||
|
|
||||||
|
#: restream/templates/restream/restreamconfig_form.html:21
|
||||||
|
#: restream/templates/restream/restreamconfig_update_form.html:21
|
||||||
|
msgid "restreamconfig_configuration_text_html"
|
||||||
|
msgstr ""
|
||||||
|
"<p>Eine Restream Konfiguration erlaubt es dir eingehende Streams in das "
|
||||||
|
"System unverändert an externe System weiterzuleiten.</p><p>Die Restream "
|
||||||
|
"Konfiguration benötigt einen vorher konfigurierten Quell-Stream und ein "
|
||||||
|
"Ziel, dass du über eine RTMP URL frei definieren kannst. Die RTMP URL sollte "
|
||||||
|
"zum Beispiel so ausschauen: <code>rtmp://servername/app/streamkey</code></"
|
||||||
|
"p><p>Du kannst natürlich mehrere Restream Konfigurationen auf einen "
|
||||||
|
"einzelnen Quell-Stream einrichten. Das erlaubt es dir von deinem Encoder nur "
|
||||||
|
"einmal einen Stream zu senden, diesen aber automatisch an mehrere Platformen "
|
||||||
|
"weiterzuleiten.</p><p>Nur Restream Konfigurationen die auf Aktiv geschaltet "
|
||||||
|
"sind werden bei einem neu eingehenden Stream ausgeführt!</p>"
|
||||||
|
|
||||||
|
#: restream/templates/restream/restreamconfig_list.html:11
|
||||||
|
msgid "restreamconfig_configuration_header"
|
||||||
|
msgstr "Restream Konfiguration"
|
||||||
|
|
||||||
|
#: restream/templates/restream/restreamconfig_list.html:16
|
||||||
|
#: rtmp/templates/rtmp/stream_list.html:16
|
||||||
|
msgid "create"
|
||||||
|
msgstr "Erstellen"
|
||||||
|
|
||||||
|
#: restream/templates/restream/restreamconfig_list.html:26
|
||||||
|
#: rtmp/templates/rtmp/stream_list.html:26
|
||||||
|
msgid "loading..."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: restream/templates/restream/restreamconfig_list.html:35
|
||||||
|
#: rtmp/templates/rtmp/stream_list.html:35
|
||||||
|
msgid "actions"
|
||||||
|
msgstr "Aktionen"
|
||||||
|
|
||||||
|
#: restream/templates/restream/restreamconfig_list.html:52
|
||||||
|
#: rtmp/templates/rtmp/stream_list.html:46
|
||||||
|
msgid "details"
|
||||||
|
msgstr "Details"
|
||||||
|
|
||||||
|
#: restream/templates/restream/restreamconfig_update_form.html:5
|
||||||
|
msgid "update_restreamconfig_configuration_header"
|
||||||
|
msgstr "Restream Konfiguration anpassen"
|
||||||
|
|
||||||
|
#: rtmp/models.py:13
|
||||||
|
msgid "rtmp_application_name"
|
||||||
|
msgstr "RTMP Application Name"
|
||||||
|
|
||||||
|
#: rtmp/models.py:16
|
||||||
|
msgid "application_verbose_name"
|
||||||
|
msgstr "Application"
|
||||||
|
|
||||||
|
#: rtmp/models.py:17
|
||||||
|
msgid "application_verbose_name_plural"
|
||||||
|
msgstr "Applications"
|
||||||
|
|
||||||
|
#: rtmp/models.py:20
|
||||||
|
msgid "aplication_class_name"
|
||||||
|
msgstr "Application"
|
||||||
|
|
||||||
|
#: rtmp/models.py:27
|
||||||
|
msgid "stream_application_help"
|
||||||
|
msgstr "Unter welcher RTMP Application gilt diese Stream ID"
|
||||||
|
|
||||||
|
#: rtmp/models.py:28
|
||||||
|
msgid "stream_stream_help"
|
||||||
|
msgstr "RTMP Stream ID"
|
||||||
|
|
||||||
|
#: rtmp/models.py:29
|
||||||
|
msgid "stream_name_help"
|
||||||
|
msgstr "Name für diesen Stream"
|
||||||
|
|
||||||
|
#: rtmp/models.py:68
|
||||||
|
msgid "stream_class_name"
|
||||||
|
msgstr "Stream"
|
||||||
|
|
||||||
|
#: rtmp/templates/rtmp/stream_confirm_delete.html:13
|
||||||
|
msgid "deleting_stream_configuration_will_also_delete_all_depending_confgurations_warning"
|
||||||
|
msgstr ""
|
||||||
|
"Achtung! Beim Löschen dieser Stream Konfiguration werden auch alle "
|
||||||
|
"abhängigen Konfigurationen gelöscht."
|
||||||
|
|
||||||
|
#: rtmp/templates/rtmp/stream_confirm_delete.html:15
|
||||||
|
#, python-format
|
||||||
|
msgid "are_you_sure_you_want_to_delete_\"%(stream_config_name)s\"?"
|
||||||
|
msgstr "Willst du wirklich \"%(stream_config_name)s\" löschen?"
|
||||||
|
|
||||||
|
#: rtmp/templates/rtmp/stream_confirm_delete.html:25
|
||||||
|
msgid "deleting_configurations_list_header"
|
||||||
|
msgstr "Diese Konfigurationen werden gelöscht"
|
||||||
|
|
||||||
|
#: rtmp/templates/rtmp/stream_detail.html:12
|
||||||
|
msgid "stream_configuration_details_header"
|
||||||
|
msgstr "Stream Konfiguration Details"
|
||||||
|
|
||||||
|
#: rtmp/templates/rtmp/stream_detail.html:30
|
||||||
|
msgid "application"
|
||||||
|
msgstr "Application"
|
||||||
|
|
||||||
|
#: rtmp/templates/rtmp/stream_detail.html:33
|
||||||
|
msgid "how_to_configure_your_encoder_header"
|
||||||
|
msgstr "Wie du deinen Encoder konfigurierst"
|
||||||
|
|
||||||
|
#: rtmp/templates/rtmp/stream_detail.html:35
|
||||||
|
msgid "set_this_stream_server_in_encoder"
|
||||||
|
msgstr "Stelle diesen Stream Server in deinem Encoder ein"
|
||||||
|
|
||||||
|
#: rtmp/templates/rtmp/stream_detail.html:37
|
||||||
|
msgid "set_this_stream_id_in_encoder"
|
||||||
|
msgstr "Stelle diese Stream ID in deinem Encoder ein"
|
||||||
|
|
||||||
|
#: rtmp/templates/rtmp/stream_detail.html:46
|
||||||
|
#: rtmp/templates/rtmp/stream_form.html:21
|
||||||
|
#: rtmp/templates/rtmp/stream_update_form.html:21
|
||||||
|
msgid "stream_configuration_text_html"
|
||||||
|
msgstr ""
|
||||||
|
"<p>Eine Stream Konfiguration erlaubt es dir einen Stream in das System zu "
|
||||||
|
"schicken</p><p>Nur Streams die zu einer vorher erstellten Konfiguration "
|
||||||
|
"zugeordnet werden können werden vom System angenommen.</p><p>Der Name dient "
|
||||||
|
"dazu den Stream beim Erstellen von weiteren Konfigurationen leicht zu "
|
||||||
|
"identifizieren. Die tatsächliche Stream ID wird dir nach dem erstellen "
|
||||||
|
"angezeigt. <strong>Halte die Stream ID auf jeden Fall geheim.</strong></p>"
|
||||||
|
|
||||||
|
#: rtmp/templates/rtmp/stream_form.html:5
|
||||||
|
msgid "create_new_stream_configuration_header"
|
||||||
|
msgstr "Neue Stream Konfiguration erstellen"
|
||||||
|
|
||||||
|
#: rtmp/templates/rtmp/stream_list.html:11
|
||||||
|
msgid "stream_configuration_header"
|
||||||
|
msgstr "Stream Konfiguration"
|
||||||
|
|
||||||
|
#: rtmp/templates/rtmp/stream_list.html:34
|
||||||
|
msgid "receiving"
|
||||||
|
msgstr "Empfange"
|
||||||
|
|
||||||
|
#: rtmp/templates/rtmp/stream_update_form.html:5
|
||||||
|
msgid "update_stream_configuration_header"
|
||||||
|
msgstr "Stream Konfiguration anpassen"
|
||||||
|
|
||||||
|
#: templates/base.html:39
|
||||||
|
#, python-format
|
||||||
|
msgid "hello_%(username)s"
|
||||||
|
msgstr "Hallo, %(username)s!"
|
||||||
|
|
||||||
|
#: templates/base.html:42
|
||||||
|
msgid "navbar_account_password_change"
|
||||||
|
msgstr "Passwort ändern"
|
||||||
|
|
||||||
|
#: templates/base.html:43
|
||||||
|
msgid "navbar_account_logout"
|
||||||
|
msgstr "Abmelden"
|
||||||
|
|
||||||
|
#: templates/base.html:47
|
||||||
|
msgid "navbar_login"
|
||||||
|
msgstr "Anmelden"
|
||||||
|
|
||||||
|
#: templates/base.html:80
|
||||||
|
msgid "navbar_configuration_pull"
|
||||||
|
msgstr "Pull"
|
||||||
|
|
||||||
|
#: templates/base.html:83
|
||||||
|
msgid "navbar_configuration_stream"
|
||||||
|
msgstr "Stream"
|
||||||
|
|
||||||
|
#: templates/base.html:86
|
||||||
|
msgid "navbar_configuration_restream"
|
||||||
|
msgstr "Restream"
|
||||||
|
|
||||||
|
#: templates/base.html:89
|
||||||
|
msgid "navbar_configuration_publish"
|
||||||
|
msgstr "Publish"
|
||||||
|
|
||||||
|
#: templates/base.html:92
|
||||||
|
msgid "navbar_configuration_record"
|
||||||
|
msgstr "Record"
|
||||||
|
|
||||||
|
#: templates/base.html:95
|
||||||
|
msgid "navbar_configuration_switch"
|
||||||
|
msgstr "Switch"
|
||||||
|
|
||||||
|
#: templates/registration/login.html:5 templates/registration/login.html:14
|
||||||
|
msgid "login"
|
||||||
|
msgstr "Anmelden"
|
||||||
|
|
||||||
|
#: templates/registration/login.html:19
|
||||||
|
msgid "forgot_password_q"
|
||||||
|
msgstr "Passwort vergessen?"
|
||||||
|
|
||||||
|
#: templates/registration/password_change_done.html:5
|
||||||
|
msgid "password_change_successful"
|
||||||
|
msgstr "Passwort erfolgreich geändert"
|
||||||
|
|
||||||
|
#: templates/registration/password_change_done.html:7
|
||||||
|
msgid "password_change_successful_text"
|
||||||
|
msgstr ""
|
||||||
|
"Das Passwort wurde erfolgreich geändert. Du kannst dich ab jetzt mit dem "
|
||||||
|
"neuen Passwort anmelden."
|
||||||
|
|
||||||
|
#: templates/registration/password_change_form.html:5
|
||||||
|
msgid "change_password"
|
||||||
|
msgstr "Passwort ändern"
|
||||||
|
|
||||||
|
#: templates/registration/password_reset_form.html:5
|
||||||
|
msgid "reset_password"
|
||||||
|
msgstr "Passwort vergessen"
|
||||||
|
|
||||||
|
#: templates/registration/password_reset_form.html:21
|
||||||
|
msgid "reset_password_text_html"
|
||||||
|
msgstr ""
|
||||||
|
"Du hast dein Passwort vergessen? Kein Problem. Gib hier die E-mail Adresse "
|
||||||
|
"deines Nutzerkonto an, und wir schicken dir einen Link zu mit dem du ein "
|
||||||
|
"neues Passwort setzen kannst."
|
||||||
|
|
||||||
|
#~ msgid "navbar_streaming"
|
||||||
|
#~ msgstr "Streaming"
|
|
@ -1,581 +1,272 @@
|
||||||
# SOME DESCRIPTIVE TITLE.
|
# Copyright (C) Chaoswest TV
|
||||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
|
||||||
# This file is distributed under the same license as the PACKAGE package.
|
# This file is distributed under the same license as the PACKAGE package.
|
||||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
# Jan Koppe <post@jankoppe.de>, 2020.
|
||||||
#
|
#
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: portier 0.6.0\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2024-05-10 14:40+0000\n"
|
"POT-Creation-Date: 2024-02-25 20:42+0000\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: Jan Koppe <post@jankoppe.de>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: english <post@chaoswest.tv>\n"
|
||||||
"Language: \n"
|
"Language: \n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
|
|
||||||
#: config/models.py:35
|
#: portier/settings.py:141
|
||||||
msgid "transcodingprofile_name_help"
|
msgid "German"
|
||||||
msgstr "Name for the transcoding profile"
|
msgstr "German"
|
||||||
|
|
||||||
#: config/models.py:37
|
#: portier/settings.py:142
|
||||||
msgid "transcodingprofile_video_map_stream_help"
|
msgid "English"
|
||||||
|
msgstr "English"
|
||||||
|
|
||||||
|
#: restream/models.py:16
|
||||||
|
msgid "restreamconfig_stream_help"
|
||||||
|
msgstr "Stream that's being used as source for the restreaming"
|
||||||
|
|
||||||
|
#: restream/models.py:17
|
||||||
|
msgid "restreamconfig_target_help"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Index of the Video stream to map into the output. Can be used to select a "
|
"Target url that the stream is being restreamed to, including schema (e.g. "
|
||||||
"specific video stream when the source contains multiple video streams."
|
"rtmp://)"
|
||||||
|
|
||||||
#: config/models.py:38
|
#: restream/models.py:18
|
||||||
msgid "transcodingprofile_video_codec_help"
|
msgid "restreamconfig_name_help"
|
||||||
|
msgstr "Name for this restream configuration"
|
||||||
|
|
||||||
|
#: restream/models.py:19
|
||||||
|
msgid "restreamconfig_activate_help"
|
||||||
|
msgstr "Only active configurations will be executed for incoming streams"
|
||||||
|
|
||||||
|
#: restream/models.py:20
|
||||||
|
#, fuzzy
|
||||||
|
#| msgid "restreamconfig_target_help"
|
||||||
|
msgid "restreamconfig_format_help"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Video Codec to use for transcoding. COPY will copy the video stream without "
|
"Target url that the stream is being restreamed to, including schema (e.g. "
|
||||||
"transcoding."
|
"rtmp://)"
|
||||||
|
|
||||||
#: config/models.py:39
|
#: restream/models.py:23
|
||||||
msgid "transcodingprofile_video_bitrate_help"
|
msgid "restreamconfig_verbose_name"
|
||||||
msgstr ""
|
msgstr "Restream configuration"
|
||||||
"Bitrate for the video stream in kbit/s. If the video codec is set to COPY, "
|
|
||||||
"this value is ignored."
|
|
||||||
|
|
||||||
#: config/models.py:40
|
#: restream/models.py:24
|
||||||
msgid "transcodingprofile_video_frame_rate_help"
|
msgid "restreamconfig_verbose_name_plural"
|
||||||
msgstr ""
|
msgstr "Restream configurations"
|
||||||
"Frame rate for the video stream. If the video codec is set to COPY, this "
|
|
||||||
"value is ignored."
|
|
||||||
|
|
||||||
#: config/models.py:41
|
#: restream/models.py:27
|
||||||
msgid "transcodingprofile_video_resolution_help"
|
msgid "restreamconfig_class_name"
|
||||||
msgstr ""
|
msgstr "Restream configuration"
|
||||||
"Scaling for the video stream. If the video codec is set to COPY, this value "
|
|
||||||
"is ignored. Use 1920:-2 to scale the video to 1080p while keeping the aspect "
|
|
||||||
"ratio."
|
|
||||||
|
|
||||||
#: config/models.py:42
|
#: restream/templates/restream/restreamconfig_confirm_delete.html:6
|
||||||
msgid "transcodingprofile_video_gop_size_help"
|
#: rtmp/templates/rtmp/stream_confirm_delete.html:6
|
||||||
msgstr ""
|
|
||||||
"Group of Pictures size for the video stream. If the video codec is set to "
|
|
||||||
"COPY, this value is ignored. A good value is 2 times the frame rate."
|
|
||||||
|
|
||||||
#: config/models.py:43
|
|
||||||
msgid "transcodingprofile_video_pixel_format_help"
|
|
||||||
msgstr ""
|
|
||||||
"Pixel format for the video stream. If the video codec is set to COPY, this "
|
|
||||||
"value is ignored. Use yuv420p for compatibility with most devices."
|
|
||||||
|
|
||||||
#: config/models.py:44
|
|
||||||
msgid "transcodingprofile_video_bitrate_mode_help"
|
|
||||||
msgstr ""
|
|
||||||
"Video bitrate mode. CBR will use a constant bitrate, VBR will use a variable "
|
|
||||||
"bitrate. For streaming, usually CBR is preferred as it keeps a consistent "
|
|
||||||
"network usage, but might not be as efficient as VBR."
|
|
||||||
|
|
||||||
#: config/models.py:46
|
|
||||||
msgid "transcodingprofile_audio_map_stream_help"
|
|
||||||
msgstr ""
|
|
||||||
"Index of the Audio stream to map into the output. Can be used to select a "
|
|
||||||
"specific audio stream when the source contains multiple audio streams."
|
|
||||||
|
|
||||||
#: config/models.py:47
|
|
||||||
msgid "transcodingprofile_audio_codec_help"
|
|
||||||
msgstr ""
|
|
||||||
"Audio Codec to use for transcoding. COPY will copy the audio stream without "
|
|
||||||
"transcoding."
|
|
||||||
|
|
||||||
#: config/models.py:48
|
|
||||||
msgid "transcodingprofile_audio_bitrate_help"
|
|
||||||
msgstr ""
|
|
||||||
"Bitrate for the audio stream in kbit/s. If the audio codec is set to COPY, "
|
|
||||||
"this value is ignored."
|
|
||||||
|
|
||||||
#: config/models.py:49
|
|
||||||
msgid "transcodingprofile_audio_channels_help"
|
|
||||||
msgstr ""
|
|
||||||
"Audio channels for the audio stream. If the audio codec is set to COPY, this "
|
|
||||||
"value is ignored. Use 2 for stereo audio."
|
|
||||||
|
|
||||||
#: config/models.py:50
|
|
||||||
msgid "transcodingprofile_audio_sample_rate_help"
|
|
||||||
msgstr ""
|
|
||||||
"Audio sample rate for the audio stream. If the audio codec is set to COPY, "
|
|
||||||
"this value is ignored. Use 48000 for compatibility with most devices."
|
|
||||||
|
|
||||||
#: config/models.py:53
|
|
||||||
msgid "transcodingprofile_verbose_name"
|
|
||||||
msgstr "Transcoding Profile"
|
|
||||||
|
|
||||||
#: config/models.py:54
|
|
||||||
msgid "transcodingprofile_verbose_name_plural"
|
|
||||||
msgstr "Transcoding Profiles"
|
|
||||||
|
|
||||||
#: config/models.py:57
|
|
||||||
msgid "transcodingprofile_class_name"
|
|
||||||
msgstr "TranscodingProfile"
|
|
||||||
|
|
||||||
#: config/models.py:82
|
|
||||||
msgid "stream_stream_help"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/models.py:83
|
|
||||||
msgid "stream_name_help"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/models.py:109
|
|
||||||
msgid "stream_class_name"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/models.py:116
|
|
||||||
msgid "srsnode_name_help"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/models.py:117
|
|
||||||
msgid "srsnode_api_base_help"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/models.py:118
|
|
||||||
msgid "srsnode_rtmp_base_help"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/models.py:119
|
|
||||||
msgid "srsnode_active_help"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/models.py:122
|
|
||||||
msgid "srsnode_verbose_name"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/models.py:123
|
|
||||||
msgid "srsnode_verbose_name_plural"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/models.py:130
|
|
||||||
msgid "srsstreaminstance_node_help"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/models.py:131
|
|
||||||
msgid "srsstreaminstance_stream_help"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/models.py:132
|
|
||||||
msgid "srsstreaminstance_last_update_help"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/models.py:133
|
|
||||||
msgid "srsstreaminstance_statusdata_help"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/models.py:136
|
|
||||||
msgid "srsstreaminstance_verbose_name"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/models.py:137
|
|
||||||
msgid "srsstreaminstance_verbose_name_plural"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/models.py:144
|
|
||||||
msgid "pull_stream_help"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/models.py:145
|
|
||||||
msgid "pull_source_help"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/models.py:146
|
|
||||||
msgid "pull_activate_help"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/models.py:147
|
|
||||||
msgid "pull_name_help"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/models.py:148 config/models.py:204
|
|
||||||
msgid "restream_transcodingprofile_help"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/models.py:151
|
|
||||||
msgid "pull_verbose_name"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/models.py:152
|
|
||||||
msgid "pull_verbose_name_plural"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/models.py:155
|
|
||||||
msgid "pull_class_name"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/models.py:199
|
|
||||||
msgid "restream_stream_help"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/models.py:200
|
|
||||||
msgid "restream_target_help"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/models.py:201
|
|
||||||
msgid "restream_name_help"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/models.py:202
|
|
||||||
msgid "restream_activate_help"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/models.py:203
|
|
||||||
msgid "restream_format_help"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/models.py:207
|
|
||||||
msgid "restream_verbose_name"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/models.py:208
|
|
||||||
msgid "restream_verbose_name_plural"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/models.py:211
|
|
||||||
msgid "restream_class_name"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/models.py:255
|
|
||||||
msgid "recordingstorage_name_help"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/models.py:262
|
|
||||||
msgid "localrecordingstorage_path_help"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/models.py:265
|
|
||||||
msgid "localrecordingstorage_verbose_name"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/models.py:266
|
|
||||||
msgid "localrecordingstorage_verbose_name_plural"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/models.py:272
|
|
||||||
msgid "s3recordingstorage_bucket_help"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/models.py:273
|
|
||||||
msgid "s3recordingstorage_access_key_help"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/models.py:274
|
|
||||||
msgid "s3recordingstorage_secret_key_help"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/models.py:275
|
|
||||||
msgid "s3recordingstorage_region_help"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/models.py:278
|
|
||||||
msgid "s3recordingstorage_verbose_name"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/models.py:279
|
|
||||||
msgid "s3recordingstorage_verbose_name_plural"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/models.py:288
|
|
||||||
msgid "recorder_stream_help"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/models.py:289
|
|
||||||
msgid "recorder_name_help"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/models.py:290
|
|
||||||
msgid "recorder_activate_help"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/templates/config/pull_confirm_delete.html:13
|
|
||||||
#: config/templates/config/restream_confirm_delete.html:13
|
|
||||||
#: config/templates/config/stream_confirm_delete.html:13
|
|
||||||
#: config/templates/config/transcodingprofile_confirm_delete.html:14
|
|
||||||
msgid "confirm_delete_header"
|
msgid "confirm_delete_header"
|
||||||
msgstr ""
|
msgstr "Confirm deletion"
|
||||||
|
|
||||||
#: config/templates/config/pull_confirm_delete.html:19
|
#: restream/templates/restream/restreamconfig_confirm_delete.html:12
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "are_you_sure_you_want_to_delete_\"%(pull_config_name)s\"?"
|
msgid "are_you_sure_you_want_to_delete_\"%(restreamconfig_config_name)s\"?"
|
||||||
msgstr ""
|
msgstr "Are you sure you want to delete \"%(restreamconfig_config_name)s\"?"
|
||||||
|
|
||||||
#: config/templates/config/pull_confirm_delete.html:22
|
#: restream/templates/restream/restreamconfig_confirm_delete.html:15
|
||||||
#: config/templates/config/pull_detail.html:27
|
#: restream/templates/restream/restreamconfig_detail.html:20
|
||||||
#: config/templates/config/restream_confirm_delete.html:22
|
#: rtmp/templates/rtmp/stream_confirm_delete.html:18
|
||||||
#: config/templates/config/restream_detail.html:27
|
#: rtmp/templates/rtmp/stream_detail.html:20
|
||||||
#: config/templates/config/stream_confirm_delete.html:25
|
|
||||||
#: config/templates/config/stream_detail.html:27
|
|
||||||
#: config/templates/config/transcodingprofile_confirm_delete.html:27
|
|
||||||
#: config/templates/config/transcodingprofile_detail.html:34
|
|
||||||
msgid "delete"
|
msgid "delete"
|
||||||
msgstr ""
|
msgstr "Delete"
|
||||||
|
|
||||||
#: config/templates/config/pull_detail.html:19
|
#: restream/templates/restream/restreamconfig_detail.html:12
|
||||||
msgid "pull_configuration_details_header"
|
msgid "restreamconfig_configuration_details_header"
|
||||||
msgstr ""
|
msgstr "Restream configuration details"
|
||||||
|
|
||||||
#: config/templates/config/pull_detail.html:24
|
#: restream/templates/restream/restreamconfig_detail.html:17
|
||||||
#: config/templates/config/restream_detail.html:24
|
#: rtmp/templates/rtmp/stream_detail.html:17
|
||||||
#: config/templates/config/stream_detail.html:24
|
|
||||||
#: config/templates/config/transcodingprofile_detail.html:27
|
|
||||||
msgid "change"
|
msgid "change"
|
||||||
msgstr "Change"
|
msgstr "Change"
|
||||||
|
|
||||||
#: config/templates/config/pull_detail.html:35
|
#: restream/templates/restream/restreamconfig_detail.html:28
|
||||||
#: config/templates/config/pull_list.html:40
|
#: restream/templates/restream/restreamconfig_list.html:33
|
||||||
#: config/templates/config/restream_detail.html:35
|
#: rtmp/templates/rtmp/stream_detail.html:28
|
||||||
#: config/templates/config/restream_list.html:40
|
#: rtmp/templates/rtmp/stream_list.html:33
|
||||||
#: config/templates/config/stream_detail.html:35
|
|
||||||
#: config/templates/config/stream_list.html:39
|
|
||||||
#: config/templates/config/transcodingprofile_list.html:43
|
|
||||||
msgid "name"
|
msgid "name"
|
||||||
msgstr "Name"
|
msgstr "Name"
|
||||||
|
|
||||||
#: config/templates/config/pull_detail.html:37
|
#: restream/templates/restream/restreamconfig_detail.html:30
|
||||||
#: config/templates/config/restream_detail.html:37
|
|
||||||
msgid "stream"
|
msgid "stream"
|
||||||
msgstr "Stream"
|
msgstr "Stream"
|
||||||
|
|
||||||
#: config/templates/config/pull_detail.html:39
|
#: restream/templates/restream/restreamconfig_detail.html:32
|
||||||
#: config/templates/config/pull_list.html:41
|
#: restream/templates/restream/restreamconfig_list.html:34
|
||||||
#: config/templates/config/restream_detail.html:39
|
|
||||||
#: config/templates/config/restream_list.html:41
|
|
||||||
msgid "active"
|
msgid "active"
|
||||||
msgstr "Active"
|
msgstr "Active"
|
||||||
|
|
||||||
#: config/templates/config/pull_detail.html:50
|
#: restream/templates/restream/restreamconfig_detail.html:43
|
||||||
msgid "configured_source_url"
|
msgid "configured_target_url"
|
||||||
msgstr ""
|
msgstr "Configured target URL"
|
||||||
|
|
||||||
#: config/templates/config/pull_form.html:12
|
#: restream/templates/restream/restreamconfig_form.html:5
|
||||||
msgid "create_new_pull_configuration_header"
|
msgid "create_new_restreamconfig_configuration_header"
|
||||||
msgstr ""
|
msgstr "Create new restream configuration"
|
||||||
|
|
||||||
#: config/templates/config/pull_form.html:21
|
#: restream/templates/restream/restreamconfig_form.html:14
|
||||||
#: config/templates/config/pull_update_form.html:21
|
#: restream/templates/restream/restreamconfig_update_form.html:14
|
||||||
#: config/templates/config/restream_form.html:21
|
#: rtmp/templates/rtmp/stream_form.html:14
|
||||||
#: config/templates/config/restream_update_form.html:21
|
#: rtmp/templates/rtmp/stream_update_form.html:14
|
||||||
#: config/templates/config/stream_form.html:21
|
|
||||||
#: config/templates/config/stream_update_form.html:21
|
|
||||||
#: templates/registration/password_change_form.html:14
|
#: templates/registration/password_change_form.html:14
|
||||||
#: templates/registration/password_reset_form.html:14
|
#: templates/registration/password_reset_form.html:14
|
||||||
msgid "submit"
|
msgid "submit"
|
||||||
msgstr ""
|
msgstr "Submit"
|
||||||
|
|
||||||
#: config/templates/config/pull_form.html:28
|
#: restream/templates/restream/restreamconfig_form.html:21
|
||||||
#: config/templates/config/pull_update_form.html:28
|
#: restream/templates/restream/restreamconfig_update_form.html:21
|
||||||
msgid "pull_configuration_text_html"
|
msgid "restreamconfig_configuration_text_html"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"<p>A restream configuration allows you to forward incoming streamswithout "
|
||||||
|
"further processing to external systems.<p><p>The restream configuration "
|
||||||
|
"needs a previously configured source stream and a target RTMP URL which you "
|
||||||
|
"can freely chose. The target RTMP URL should look e.g. like this: "
|
||||||
|
"<code>rtmp://servername/app/streamkey</code></p>You can of course create "
|
||||||
|
"multiple restream configurations with the same source stream. This allows "
|
||||||
|
"you to only send one stream from your encoder, but distribute this to "
|
||||||
|
"multiple platforms.</p><p>Only restream configurations that are marked "
|
||||||
|
"active will be executed for an incoming stream!</p>"
|
||||||
|
|
||||||
#: config/templates/config/pull_list.html:18
|
#: restream/templates/restream/restreamconfig_list.html:11
|
||||||
msgid "pull_configuration_header"
|
msgid "restreamconfig_configuration_header"
|
||||||
msgstr ""
|
msgstr "Restream configuration"
|
||||||
|
|
||||||
#: config/templates/config/pull_list.html:23
|
#: restream/templates/restream/restreamconfig_list.html:16
|
||||||
#: config/templates/config/restream_list.html:23
|
#: rtmp/templates/rtmp/stream_list.html:16
|
||||||
#: config/templates/config/stream_list.html:22
|
|
||||||
#: config/templates/config/transcodingprofile_list.html:25
|
|
||||||
msgid "create"
|
msgid "create"
|
||||||
msgstr ""
|
msgstr "Create"
|
||||||
|
|
||||||
#: config/templates/config/pull_list.html:33
|
#: restream/templates/restream/restreamconfig_list.html:26
|
||||||
#: config/templates/config/restream_list.html:33
|
#: rtmp/templates/rtmp/stream_list.html:26
|
||||||
#: config/templates/config/stream_list.html:32
|
|
||||||
#: config/templates/config/transcodingprofile_list.html:36
|
|
||||||
msgid "loading..."
|
msgid "loading..."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: config/templates/config/pull_list.html:42
|
#: restream/templates/restream/restreamconfig_list.html:35
|
||||||
#: config/templates/config/restream_list.html:42
|
#: rtmp/templates/rtmp/stream_list.html:35
|
||||||
#: config/templates/config/stream_list.html:41
|
|
||||||
#: config/templates/config/transcodingprofile_list.html:44
|
|
||||||
msgid "actions"
|
msgid "actions"
|
||||||
msgstr ""
|
msgstr "Actions"
|
||||||
|
|
||||||
#: config/templates/config/pull_list.html:59
|
#: restream/templates/restream/restreamconfig_list.html:52
|
||||||
#: config/templates/config/restream_list.html:59
|
#: rtmp/templates/rtmp/stream_list.html:46
|
||||||
#: config/templates/config/stream_list.html:52
|
|
||||||
#: config/templates/config/transcodingprofile_list.html:55
|
|
||||||
msgid "details"
|
msgid "details"
|
||||||
msgstr ""
|
msgstr "Details"
|
||||||
|
|
||||||
#: config/templates/config/pull_update_form.html:12
|
#: restream/templates/restream/restreamconfig_update_form.html:5
|
||||||
msgid "update_pull_configuration_header"
|
msgid "update_restreamconfig_configuration_header"
|
||||||
msgstr ""
|
msgstr "Update restream configuration"
|
||||||
|
|
||||||
#: config/templates/config/restream_confirm_delete.html:19
|
#: rtmp/models.py:13
|
||||||
#, python-format
|
msgid "rtmp_application_name"
|
||||||
msgid "are_you_sure_you_want_to_delete_\"%(restream_config_name)s\"?"
|
msgstr "RTMP application name"
|
||||||
msgstr ""
|
|
||||||
"Are you sure you want to delete \"%(restream_config_name)s\"? This action "
|
|
||||||
"cannot be undone."
|
|
||||||
|
|
||||||
#: config/templates/config/restream_detail.html:19
|
#: rtmp/models.py:16
|
||||||
msgid "restream_configuration_details_header"
|
msgid "application_verbose_name"
|
||||||
msgstr ""
|
msgstr "RTMP application"
|
||||||
|
|
||||||
#: config/templates/config/restream_detail.html:50
|
#: rtmp/models.py:17
|
||||||
msgid "configured_target_url"
|
msgid "application_verbose_name_plural"
|
||||||
msgstr ""
|
msgstr "RTMP applications"
|
||||||
"Configured target URL. This is the URL where the stream will be restreamed "
|
|
||||||
"to."
|
|
||||||
|
|
||||||
#: config/templates/config/restream_form.html:12
|
#: rtmp/models.py:20
|
||||||
msgid "create_new_restream_configuration_header"
|
msgid "aplication_class_name"
|
||||||
msgstr ""
|
msgstr "Application"
|
||||||
|
|
||||||
#: config/templates/config/restream_form.html:28
|
#: rtmp/models.py:27
|
||||||
#: config/templates/config/restream_update_form.html:28
|
msgid "stream_application_help"
|
||||||
msgid "restream_configuration_text_html"
|
msgstr "Application which the stream is assigned to"
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: config/templates/config/restream_list.html:18
|
#: rtmp/models.py:28
|
||||||
msgid "restream_configuration_header"
|
msgid "stream_stream_help"
|
||||||
msgstr "Restream Configuration"
|
msgstr "Stream ID for this stream"
|
||||||
|
|
||||||
#: config/templates/config/restream_update_form.html:12
|
#: rtmp/models.py:29
|
||||||
msgid "update_restream_configuration_header"
|
msgid "stream_name_help"
|
||||||
msgstr "Change Restream Configuration"
|
msgstr "Name for this stream"
|
||||||
|
|
||||||
#: config/templates/config/stream_confirm_delete.html:20
|
#: rtmp/models.py:68
|
||||||
|
msgid "stream_class_name"
|
||||||
|
msgstr "Stream"
|
||||||
|
|
||||||
|
#: rtmp/templates/rtmp/stream_confirm_delete.html:13
|
||||||
msgid "deleting_stream_configuration_will_also_delete_all_depending_confgurations_warning"
|
msgid "deleting_stream_configuration_will_also_delete_all_depending_confgurations_warning"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Deleting this stream configuration will also delete all depending "
|
"Attention! Deleting this stream configuration will also delete all depending "
|
||||||
"configurations. This action cannot be undone."
|
"configurations."
|
||||||
|
|
||||||
#: config/templates/config/stream_confirm_delete.html:22
|
#: rtmp/templates/rtmp/stream_confirm_delete.html:15
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "are_you_sure_you_want_to_delete_\"%(stream_config_name)s\"?"
|
msgid "are_you_sure_you_want_to_delete_\"%(stream_config_name)s\"?"
|
||||||
msgstr ""
|
msgstr "Are you sure you want to delete \"%(stream_config_name)s\"?"
|
||||||
"Are you sure you want to delete \"%(stream_config_name)s\"? This will also "
|
|
||||||
"delete all depending configurations. This action cannot be undone."
|
|
||||||
|
|
||||||
#: config/templates/config/stream_confirm_delete.html:32
|
#: rtmp/templates/rtmp/stream_confirm_delete.html:25
|
||||||
msgid "deleting_configurations_list_header"
|
msgid "deleting_configurations_list_header"
|
||||||
msgstr "Stream Configurations"
|
msgstr "List of deleted configurations"
|
||||||
|
|
||||||
#: config/templates/config/stream_detail.html:19
|
#: rtmp/templates/rtmp/stream_detail.html:12
|
||||||
msgid "stream_configuration_details_header"
|
msgid "stream_configuration_details_header"
|
||||||
msgstr "Stream Configuration Details"
|
msgstr "Stream configuration details"
|
||||||
|
|
||||||
#: config/templates/config/stream_detail.html:38
|
#: rtmp/templates/rtmp/stream_detail.html:30
|
||||||
|
msgid "application"
|
||||||
|
msgstr "Application"
|
||||||
|
|
||||||
|
#: rtmp/templates/rtmp/stream_detail.html:33
|
||||||
msgid "how_to_configure_your_encoder_header"
|
msgid "how_to_configure_your_encoder_header"
|
||||||
msgstr ""
|
msgstr "How to configure your encoder"
|
||||||
|
|
||||||
#: config/templates/config/stream_detail.html:40
|
#: rtmp/templates/rtmp/stream_detail.html:35
|
||||||
msgid "set_this_stream_server_in_encoder"
|
msgid "set_this_stream_server_in_encoder"
|
||||||
msgstr "Set one of these stream servers in your encoder."
|
msgstr "Set this stream server in your encoder"
|
||||||
|
|
||||||
#: config/templates/config/stream_detail.html:49
|
#: rtmp/templates/rtmp/stream_detail.html:37
|
||||||
msgid "set_this_stream_id_in_encoder"
|
msgid "set_this_stream_id_in_encoder"
|
||||||
msgstr "Set this stream ID as the key in your encoder."
|
msgstr "Set this stream ID in your encoder"
|
||||||
|
|
||||||
#: config/templates/config/stream_detail.html:58
|
#: rtmp/templates/rtmp/stream_detail.html:46
|
||||||
#: config/templates/config/stream_form.html:28
|
#: rtmp/templates/rtmp/stream_form.html:21
|
||||||
#: config/templates/config/stream_update_form.html:28
|
#: rtmp/templates/rtmp/stream_update_form.html:21
|
||||||
msgid "stream_configuration_text_html"
|
msgid "stream_configuration_text_html"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"<p>A stream configuration allows you to send a stream into the system.</"
|
||||||
|
"p><p>Only streams that can be matched to a previously configured stream will "
|
||||||
|
"be accepted by the system.</p><p>The only purpose of the name is to make "
|
||||||
|
"this stream easily identifiable when creating further configurations.The "
|
||||||
|
"actual stream ID will be shown to you after creation. <strong>Always keep "
|
||||||
|
"your stream ID secret.</strong></p>"
|
||||||
|
|
||||||
#: config/templates/config/stream_form.html:12
|
#: rtmp/templates/rtmp/stream_form.html:5
|
||||||
msgid "create_new_stream_configuration_header"
|
msgid "create_new_stream_configuration_header"
|
||||||
msgstr "Create new Stream Configuration"
|
msgstr "Create new stream configuration"
|
||||||
|
|
||||||
#: config/templates/config/stream_list.html:17
|
#: rtmp/templates/rtmp/stream_list.html:11
|
||||||
msgid "stream_configuration_header"
|
msgid "stream_configuration_header"
|
||||||
msgstr "Stream Configuration"
|
msgstr "Stream configuration"
|
||||||
|
|
||||||
#: config/templates/config/stream_list.html:40
|
#: rtmp/templates/rtmp/stream_list.html:34
|
||||||
msgid "receiving"
|
msgid "receiving"
|
||||||
msgstr "Reseiving"
|
msgstr "Receiving"
|
||||||
|
|
||||||
#: config/templates/config/stream_update_form.html:12
|
#: rtmp/templates/rtmp/stream_update_form.html:5
|
||||||
msgid "update_stream_configuration_header"
|
msgid "update_stream_configuration_header"
|
||||||
msgstr "Edit Stream Configuration"
|
msgstr "Change stream configuration"
|
||||||
|
|
||||||
#: config/templates/config/transcodingprofile_detail.html:18
|
|
||||||
#, fuzzy
|
|
||||||
#| msgid "stream_configuration_details_header"
|
|
||||||
msgid "transcodingprofile_configuration_details_header"
|
|
||||||
msgstr "Stream Configuration Details"
|
|
||||||
|
|
||||||
#: config/templates/config/transcodingprofile_detail.html:44
|
|
||||||
msgid "transcodingprofile_video_map_stream"
|
|
||||||
msgstr "Stream"
|
|
||||||
|
|
||||||
#: config/templates/config/transcodingprofile_detail.html:46
|
|
||||||
msgid "transcodingprofile_video_codec"
|
|
||||||
msgstr "Codec"
|
|
||||||
|
|
||||||
#: config/templates/config/transcodingprofile_detail.html:48
|
|
||||||
msgid "transcodingprofile_video_bitrate"
|
|
||||||
msgstr "Bitrate"
|
|
||||||
|
|
||||||
#: config/templates/config/transcodingprofile_detail.html:50
|
|
||||||
msgid "transcodingprofile_video_bitrate_mode"
|
|
||||||
msgstr "Mode"
|
|
||||||
|
|
||||||
#: config/templates/config/transcodingprofile_detail.html:52
|
|
||||||
msgid "transcodingprofile_video_gop_size"
|
|
||||||
msgstr "GOP Size"
|
|
||||||
|
|
||||||
#: config/templates/config/transcodingprofile_detail.html:54
|
|
||||||
msgid "transcodingprofile_video_pixel_format"
|
|
||||||
msgstr "Pixelfmt"
|
|
||||||
|
|
||||||
#: config/templates/config/transcodingprofile_detail.html:56
|
|
||||||
msgid "transcodingprofile_video_resolution"
|
|
||||||
msgstr "Resolution"
|
|
||||||
|
|
||||||
#: config/templates/config/transcodingprofile_detail.html:58
|
|
||||||
msgid "transcodingprofile_video_frame_rate"
|
|
||||||
msgstr "Frame Rate"
|
|
||||||
|
|
||||||
#: config/templates/config/transcodingprofile_detail.html:65
|
|
||||||
msgid "transcodingprofile_audio_map_stream"
|
|
||||||
msgstr "Stream"
|
|
||||||
|
|
||||||
#: config/templates/config/transcodingprofile_detail.html:67
|
|
||||||
msgid "transcodingprofile_audio_codec"
|
|
||||||
msgstr "Codec"
|
|
||||||
|
|
||||||
#: config/templates/config/transcodingprofile_detail.html:69
|
|
||||||
msgid "transcodingprofile_audio_bitrate"
|
|
||||||
msgstr "Bitrate"
|
|
||||||
|
|
||||||
#: config/templates/config/transcodingprofile_detail.html:71
|
|
||||||
msgid "transcodingprofile_audio_channels"
|
|
||||||
msgstr "Channels"
|
|
||||||
|
|
||||||
#: config/templates/config/transcodingprofile_detail.html:73
|
|
||||||
msgid "transcodingprofile_audio_sample_rate"
|
|
||||||
msgstr "Samplerate"
|
|
||||||
|
|
||||||
#: config/templates/config/transcodingprofile_list.html:16
|
|
||||||
msgid "transcodingprofile_configuration_header"
|
|
||||||
msgstr "Transcoding Profile Configuration"
|
|
||||||
|
|
||||||
#: config/util.py:8
|
|
||||||
#, python-format
|
|
||||||
msgid ""
|
|
||||||
"Invalid URL: %(value)s. Must start with one of the following: %(protocols)s"
|
|
||||||
msgstr ""
|
|
||||||
"Invalid URL: %(value)s. Must start with one of the following: %(protocols)s"
|
|
||||||
|
|
||||||
#: portier/settings.py:143
|
|
||||||
msgid "English"
|
|
||||||
msgstr "English"
|
|
||||||
|
|
||||||
#: templates/base.html:39
|
#: templates/base.html:39
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "hello_%(username)s"
|
msgid "hello_%(username)s"
|
||||||
msgstr "Hello, %(username)s"
|
msgstr "Hello, %(username)s!"
|
||||||
|
|
||||||
#: templates/base.html:42
|
#: templates/base.html:42
|
||||||
msgid "navbar_account_password_change"
|
msgid "navbar_account_password_change"
|
||||||
msgstr "Change Password"
|
msgstr "Change password"
|
||||||
|
|
||||||
#: templates/base.html:43
|
#: templates/base.html:43
|
||||||
msgid "navbar_account_logout"
|
msgid "navbar_account_logout"
|
||||||
|
@ -585,31 +276,27 @@ msgstr "Logout"
|
||||||
msgid "navbar_login"
|
msgid "navbar_login"
|
||||||
msgstr "Login"
|
msgstr "Login"
|
||||||
|
|
||||||
#: templates/base.html:81
|
#: templates/base.html:80
|
||||||
|
msgid "navbar_configuration_pull"
|
||||||
|
msgstr "Pull"
|
||||||
|
|
||||||
|
#: templates/base.html:83
|
||||||
msgid "navbar_configuration_stream"
|
msgid "navbar_configuration_stream"
|
||||||
msgstr "Stream"
|
msgstr "Stream"
|
||||||
|
|
||||||
#: templates/base.html:84
|
|
||||||
msgid "navbar_configuration_transcodingprofiles"
|
|
||||||
msgstr "Profiles"
|
|
||||||
|
|
||||||
#: templates/base.html:86
|
#: templates/base.html:86
|
||||||
msgid "navbar_configuration_restream"
|
msgid "navbar_configuration_restream"
|
||||||
msgstr "Restream"
|
msgstr "Restream"
|
||||||
|
|
||||||
#: templates/base.html:89
|
#: templates/base.html:89
|
||||||
msgid "navbar_configuration_pull"
|
|
||||||
msgstr "Pull"
|
|
||||||
|
|
||||||
#: templates/base.html:92
|
|
||||||
msgid "navbar_configuration_publish"
|
msgid "navbar_configuration_publish"
|
||||||
msgstr "Publish"
|
msgstr "Publish"
|
||||||
|
|
||||||
#: templates/base.html:95
|
#: templates/base.html:92
|
||||||
msgid "navbar_configuration_record"
|
msgid "navbar_configuration_record"
|
||||||
msgstr "Record"
|
msgstr "Record"
|
||||||
|
|
||||||
#: templates/base.html:98
|
#: templates/base.html:95
|
||||||
msgid "navbar_configuration_switch"
|
msgid "navbar_configuration_switch"
|
||||||
msgstr "Switch"
|
msgstr "Switch"
|
||||||
|
|
||||||
|
@ -619,34 +306,32 @@ msgstr "Login"
|
||||||
|
|
||||||
#: templates/registration/login.html:19
|
#: templates/registration/login.html:19
|
||||||
msgid "forgot_password_q"
|
msgid "forgot_password_q"
|
||||||
msgstr "Forgot Password?"
|
msgstr "Did you forget your password?"
|
||||||
|
|
||||||
#: templates/registration/password_change_done.html:5
|
#: templates/registration/password_change_done.html:5
|
||||||
msgid "password_change_successful"
|
msgid "password_change_successful"
|
||||||
msgstr "Password change was successful."
|
msgstr "Password change was successful"
|
||||||
|
|
||||||
#: templates/registration/password_change_done.html:7
|
#: templates/registration/password_change_done.html:7
|
||||||
msgid "password_change_successful_text"
|
msgid "password_change_successful_text"
|
||||||
msgstr "The password has been changed. Please login with your new password."
|
msgstr ""
|
||||||
|
"The password has succesfully been changed. From now on you can login with "
|
||||||
|
"your new password."
|
||||||
|
|
||||||
#: templates/registration/password_change_form.html:5
|
#: templates/registration/password_change_form.html:5
|
||||||
msgid "change_password"
|
msgid "change_password"
|
||||||
msgstr "Change Password"
|
msgstr "Change password"
|
||||||
|
|
||||||
#: templates/registration/password_reset_form.html:5
|
#: templates/registration/password_reset_form.html:5
|
||||||
msgid "reset_password"
|
msgid "reset_password"
|
||||||
msgstr "Reset Password"
|
msgstr "Password forgotten?"
|
||||||
|
|
||||||
#: templates/registration/password_reset_form.html:21
|
#: templates/registration/password_reset_form.html:21
|
||||||
msgid "reset_password_text_html"
|
msgid "reset_password_text_html"
|
||||||
msgstr "Reset your password by entering your email address."
|
msgstr ""
|
||||||
|
"Did you forget your password? No worries. Enter the e-mail address of your "
|
||||||
|
"user account here. We will send an e-mail with a link to you, which you can "
|
||||||
|
"use to reset the password."
|
||||||
|
|
||||||
#, fuzzy, python-format
|
#~ msgid "navbar_streaming"
|
||||||
#~| msgid "are_you_sure_you_want_to_delete_\"%(restream_config_name)s\"?"
|
#~ msgstr "Streaming"
|
||||||
#~ msgid "are_you_sure_you_want_to_delete_\"%(transcodingprofile_config_name)s\"?"
|
|
||||||
#~ msgstr ""
|
|
||||||
#~ "Are you sure you want to delete \"%(restream_config_name)s\"? This action "
|
|
||||||
#~ "cannot be undone."
|
|
||||||
|
|
||||||
#~ msgid "German"
|
|
||||||
#~ msgstr "German"
|
|
||||||
|
|
|
@ -2,10 +2,7 @@ from ninja import NinjaAPI, ModelSchema, Router
|
||||||
from ninja.security import django_auth
|
from ninja.security import django_auth
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
import config.api as config_api
|
from config.api import router as config_router
|
||||||
#from config.api import router as config_router
|
|
||||||
#from config.api.recorder import router as config_recorder_router
|
|
||||||
#from config.api.recorder import router as config_recorder_router
|
|
||||||
from concierge.api import router as concierge_router
|
from concierge.api import router as concierge_router
|
||||||
|
|
||||||
core_router = Router()
|
core_router = Router()
|
||||||
|
@ -28,10 +25,6 @@ api = NinjaAPI(
|
||||||
csrf=False, # Disable CSRF for now
|
csrf=False, # Disable CSRF for now
|
||||||
)
|
)
|
||||||
|
|
||||||
api.add_router("/", core_router, auth=django_auth, tags=["Core API"])
|
api.add_router("/", core_router, auth=django_auth, tags=["Core"])
|
||||||
api.add_router("/config/recorder/", config_api.recorder.router, auth=django_auth, tags=["Recorder Configuration API"])
|
api.add_router("/config/", config_router, auth=django_auth, tags=["Configuration"])
|
||||||
api.add_router("/config/pull/", config_api.pull.router, auth=django_auth, tags=["Pull Configuration API"])
|
api.add_router("/concierge/", concierge_router, auth=None, tags=["Concierge"])
|
||||||
api.add_router("/config/stream/", config_api.stream.router, auth=django_auth, tags=["Stream Configuration API"])
|
|
||||||
api.add_router("/config/restream/", config_api.restream.router, auth=django_auth, tags=["Resteam Configuration API"])
|
|
||||||
api.add_router("/config/transcodingprofile/", config_api.transcodingprofile.router, auth=django_auth, tags=["Transcoding Profile Configuration API"])
|
|
||||||
api.add_router("/concierge/", concierge_router, auth=None, tags=["Concierge API"])
|
|
||||||
|
|
|
@ -139,7 +139,7 @@ USE_I18N = True
|
||||||
USE_TZ = True
|
USE_TZ = True
|
||||||
|
|
||||||
LANGUAGES = [
|
LANGUAGES = [
|
||||||
#('de', _('German')),
|
('de', _('German')),
|
||||||
('en', _('English')),
|
('en', _('English')),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -196,7 +196,7 @@ DJANGO_CELERY_BEAT_TZ_AWARE = False
|
||||||
|
|
||||||
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
|
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
|
||||||
|
|
||||||
if DEBUG:
|
if DEBUG == "LOLOLOL":
|
||||||
LOGGING = {
|
LOGGING = {
|
||||||
'version': 1,
|
'version': 1,
|
||||||
'disable_existing_loggers': False,
|
'disable_existing_loggers': False,
|
||||||
|
|
|
@ -1,34 +1,37 @@
|
||||||
var app = new Vue({
|
var app = new Vue({
|
||||||
el: "#app",
|
el: '#app',
|
||||||
data: {
|
data: {
|
||||||
cfgs: [],
|
cfgs: [],
|
||||||
isLoading: true,
|
isLoading: true
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
detailLink(id) {
|
detailLink(id) {
|
||||||
return `${id}/`;
|
return `${id}/`
|
||||||
},
|
},
|
||||||
deleteLink(id) {
|
deleteLink(id) {
|
||||||
return `${id}/delete`;
|
return `${id}/delete`
|
||||||
},
|
},
|
||||||
toggleActive(cfg) {
|
toggleActive(cfg) {
|
||||||
axios
|
axios
|
||||||
.patch("/api/v2/config/pull/" + cfg.id, { active: !cfg.active })
|
.patch('/api/v2/config/pulls/' + cfg.id, { active: !cfg.active })
|
||||||
.then((response) => {
|
.then(response => {
|
||||||
i = this.cfgs.findIndex((obj) => obj.id == cfg.id);
|
i = this.cfgs.findIndex((obj => obj.id == cfg.id))
|
||||||
Vue.set(this.cfgs, i, response.data);
|
Vue.set(this.cfgs, i, response.data)
|
||||||
});
|
}
|
||||||
|
)
|
||||||
},
|
},
|
||||||
fetchData() {
|
fetchData() {
|
||||||
axios.get("/api/v2/config/pull").then((response) => {
|
axios
|
||||||
this.cfgs = response.data;
|
.get('/api/v2/config/pulls')
|
||||||
this.isLoading = false;
|
.then(response => {
|
||||||
});
|
this.cfgs = response.data
|
||||||
},
|
this.isLoading = false
|
||||||
|
})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
axios.defaults.xsrfCookieName = "csrftoken";
|
axios.defaults.xsrfCookieName = 'csrftoken'
|
||||||
axios.defaults.xsrfHeaderName = "X-CSRFTOKEN";
|
axios.defaults.xsrfHeaderName = 'X-CSRFTOKEN'
|
||||||
this.fetchData();
|
this.fetchData()
|
||||||
},
|
}
|
||||||
});
|
})
|
||||||
|
|
|
@ -1,34 +1,37 @@
|
||||||
var app = new Vue({
|
var app = new Vue({
|
||||||
el: "#app",
|
el: '#app',
|
||||||
data: {
|
data: {
|
||||||
cfgs: [],
|
cfgs: [],
|
||||||
isLoading: true,
|
isLoading: true
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
detailLink(id) {
|
detailLink(id) {
|
||||||
return `${id}/`;
|
return `${id}/`
|
||||||
},
|
},
|
||||||
deleteLink(id) {
|
deleteLink(id) {
|
||||||
return `${id}/delete`;
|
return `${id}/delete`
|
||||||
},
|
},
|
||||||
toggleActive(cfg) {
|
toggleActive(cfg) {
|
||||||
axios
|
axios
|
||||||
.patch("/api/v2/config/restream/" + cfg.id, { active: !cfg.active })
|
.patch('/api/v2/config/restreams/' + cfg.id, { active: !cfg.active })
|
||||||
.then((response) => {
|
.then(response => {
|
||||||
i = this.cfgs.findIndex((obj) => obj.id == cfg.id);
|
i = this.cfgs.findIndex((obj => obj.id == cfg.id))
|
||||||
Vue.set(this.cfgs, i, response.data);
|
Vue.set(this.cfgs, i, response.data)
|
||||||
});
|
}
|
||||||
|
)
|
||||||
},
|
},
|
||||||
fetchData() {
|
fetchData() {
|
||||||
axios.get("/api/v2/config/restream").then((response) => {
|
axios
|
||||||
this.cfgs = response.data;
|
.get('/api/v2/config/restreams')
|
||||||
this.isLoading = false;
|
.then(response => {
|
||||||
});
|
this.cfgs = response.data
|
||||||
},
|
this.isLoading = false
|
||||||
|
})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
axios.defaults.xsrfCookieName = "csrftoken";
|
axios.defaults.xsrfCookieName = 'csrftoken'
|
||||||
axios.defaults.xsrfHeaderName = "X-CSRFTOKEN";
|
axios.defaults.xsrfHeaderName = 'X-CSRFTOKEN'
|
||||||
this.fetchData();
|
this.fetchData()
|
||||||
},
|
}
|
||||||
});
|
})
|
||||||
|
|
|
@ -1,35 +1,34 @@
|
||||||
var app = new Vue({
|
var app = new Vue({
|
||||||
el: "#app",
|
el: '#app',
|
||||||
data: {
|
data: {
|
||||||
streams: [],
|
streams: [],
|
||||||
isLoading: true,
|
isLoading: true
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
isPublishing(stream) {
|
isPublishing(stream) {
|
||||||
return stream.publish_counter > 0;
|
return stream.publish_counter > 0
|
||||||
},
|
},
|
||||||
detailLink(id) {
|
detailLink(id) {
|
||||||
return `${id}/`;
|
return `${id}/`
|
||||||
},
|
},
|
||||||
deleteLink(id) {
|
deleteLink(id) {
|
||||||
return `${id}/delete`;
|
return `${id}/delete`
|
||||||
},
|
},
|
||||||
fetchData() {
|
fetchData() {
|
||||||
axios.get("/api/v2/config/stream").then((response) => {
|
axios
|
||||||
this.streams = response.data;
|
.get('/api/v2/config/streams')
|
||||||
this.isLoading = false;
|
.then(response => {
|
||||||
});
|
this.streams = response.data
|
||||||
},
|
this.isLoading = false
|
||||||
|
})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
axios.defaults.xsrfCookieName = "csrftoken";
|
axios.defaults.xsrfCookieName = 'csrftoken'
|
||||||
axios.defaults.xsrfHeaderName = "X-CSRFTOKEN";
|
axios.defaults.xsrfHeaderName = 'X-CSRFTOKEN'
|
||||||
|
this.fetchData()
|
||||||
|
setInterval(function () {
|
||||||
this.fetchData();
|
this.fetchData();
|
||||||
setInterval(
|
}.bind(this), 1000);
|
||||||
function () {
|
}
|
||||||
this.fetchData();
|
})
|
||||||
}.bind(this),
|
|
||||||
1000,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
var app = new Vue({
|
|
||||||
el: "#app",
|
|
||||||
data: {
|
|
||||||
cfgs: [],
|
|
||||||
isLoading: true,
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
detailLink(id) {
|
|
||||||
return `${id}/`;
|
|
||||||
},
|
|
||||||
deleteLink(id) {
|
|
||||||
return `${id}/delete`;
|
|
||||||
},
|
|
||||||
fetchData() {
|
|
||||||
axios.get("/api/v2/config/transcodingprofile").then((response) => {
|
|
||||||
this.cfgs = response.data;
|
|
||||||
this.isLoading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
axios.defaults.xsrfCookieName = "csrftoken";
|
|
||||||
axios.defaults.xsrfHeaderName = "X-CSRFTOKEN";
|
|
||||||
this.fetchData();
|
|
||||||
},
|
|
||||||
});
|
|
|
@ -80,8 +80,6 @@
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link{% if not perms.config.add_stream %} disabled{% endif %}{% if section == "stream" %} active {% endif %}" href="{% url 'config:stream_list' %}">{% fa5_icon 'dot-circle' %} {% trans "navbar_configuration_stream" %}</a>
|
<a class="nav-link{% if not perms.config.add_stream %} disabled{% endif %}{% if section == "stream" %} active {% endif %}" href="{% url 'config:stream_list' %}">{% fa5_icon 'dot-circle' %} {% trans "navbar_configuration_stream" %}</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link{% if not perms.config.add_transcodingprofile %} disabled{% endif %}{% if section == "transcodingprofile" %} active {% endif %}" href="{% url 'config:transcodingprofile_list' %}">{% fa5_icon 'sliders-h' %} {% trans "navbar_configuration_transcodingprofiles" %}</a>
|
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link{% if not perms.config.add_restream %} disabled{% endif %}{% if section == "restream" %} active {% endif %}" href="{% url 'config:restream_list' %}">{% fa5_icon 'expand-arrows-alt' %} {% trans "navbar_configuration_restream" %}</a>
|
<a class="nav-link{% if not perms.config.add_restream %} disabled{% endif %}{% if section == "restream" %} active {% endif %}" href="{% url 'config:restream_list' %}">{% fa5_icon 'expand-arrows-alt' %} {% trans "navbar_configuration_restream" %}</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
Loading…
Reference in New Issue