Can now stream transcoded version of audio tracks \o/

This commit is contained in:
Eliot Berriot 2018-02-18 23:49:42 +01:00
parent ddea5f1825
commit 1cfdf31e00
No known key found for this signature in database
GPG Key ID: DD6965E2476E5C27
2 changed files with 63 additions and 0 deletions

View File

@ -0,0 +1,23 @@
from django import forms
from . import models
class TranscodeForm(forms.Form):
FORMAT_CHOICES = [
('ogg', 'ogg'),
('mp3', 'mp3'),
]
to = forms.ChoiceField(choices=FORMAT_CHOICES)
BITRATE_CHOICES = [
(64, '64'),
(128, '128'),
(256, '256'),
]
bitrate = forms.ChoiceField(
choices=BITRATE_CHOICES, required=False)
track_file = forms.ModelChoiceField(
queryset=models.TrackFile.objects.all()
)

View File

@ -1,11 +1,16 @@
import ffmpeg
import os import os
import json import json
import subprocess
import unicodedata import unicodedata
import urllib import urllib
from django.urls import reverse from django.urls import reverse
from django.db import models, transaction from django.db import models, transaction
from django.db.models.functions import Length from django.db.models.functions import Length
from django.conf import settings from django.conf import settings
from django.http import StreamingHttpResponse
from rest_framework import viewsets, views, mixins from rest_framework import viewsets, views, mixins
from rest_framework.decorators import detail_route, list_route from rest_framework.decorators import detail_route, list_route
from rest_framework.response import Response from rest_framework.response import Response
@ -19,6 +24,7 @@ from funkwhale_api.common.permissions import (
ConditionalAuthentication, HasModelPermission) ConditionalAuthentication, HasModelPermission)
from taggit.models import Tag from taggit.models import Tag
from . import forms
from . import models from . import models
from . import serializers from . import serializers
from . import importers from . import importers
@ -183,6 +189,40 @@ class TrackFileViewSet(viewsets.ReadOnlyModelViewSet):
f.audio_file.url) f.audio_file.url)
return response return response
@list_route(methods=['get'])
def viewable(self, request, *args, **kwargs):
return Response({}, status=200)
@list_route(methods=['get'])
def transcode(self, request, *args, **kwargs):
form = forms.TranscodeForm(request.GET)
if not form.is_valid():
return Response(form.errors, status=400)
f = form.cleaned_data['track_file']
output_kwargs = {
'format': form.cleaned_data['to']
}
args = (ffmpeg
.input(f.audio_file.path)
.output('pipe:', **output_kwargs)
.get_args()
)
# we use a generator here so the view return immediatly and send
# file chunk to the browser, instead of blocking a few seconds
def _transcode():
p = subprocess.Popen(
['ffmpeg'] + args,
stdout=subprocess.PIPE)
for line in p.stdout:
yield line
response = StreamingHttpResponse(
_transcode(), status=200,
content_type=form.cleaned_data['to'])
return response
class TagViewSet(viewsets.ReadOnlyModelViewSet): class TagViewSet(viewsets.ReadOnlyModelViewSet):
queryset = Tag.objects.all().order_by('name') queryset = Tag.objects.all().order_by('name')