mirror of
https://github.com/spl0k/supysonic.git
synced 2024-12-22 17:06:17 +00:00
Transcoding
This commit is contained in:
parent
92add62a7c
commit
2d0774abeb
70
api/media.py
70
api/media.py
@ -1,14 +1,23 @@
|
||||
# coding: utf-8
|
||||
|
||||
from flask import request, send_file
|
||||
from flask import request, send_file, Response
|
||||
import os.path
|
||||
from PIL import Image
|
||||
import subprocess
|
||||
|
||||
import config
|
||||
import config, scanner
|
||||
from web import app
|
||||
from db import Track, Folder, User, now, session
|
||||
from api import get_entity
|
||||
|
||||
def prepare_transcoding_cmdline(base_cmdline, input_file, input_format, output_format, output_bitrate):
|
||||
if not base_cmdline:
|
||||
return None
|
||||
ret = base_cmdline.split()
|
||||
for i in xrange(len(ret)):
|
||||
ret[i] = ret[i].replace('%srcpath', input_file).replace('%srcfmt', input_format).replace('%outfmt', output_format).replace('%outrate', str(output_bitrate))
|
||||
return ret
|
||||
|
||||
@app.route('/rest/stream.view', methods = [ 'GET', 'POST' ])
|
||||
def stream_media():
|
||||
status, res = get_entity(request, Track)
|
||||
@ -19,20 +28,58 @@ def stream_media():
|
||||
if format:
|
||||
format = format.lower()
|
||||
|
||||
if format != 'raw':
|
||||
do_transcoding = False
|
||||
src_suffix = res.suffix()
|
||||
dst_suffix = res.suffix()
|
||||
dst_bitrate = res.bitrate
|
||||
dst_mimetype = res.content_type
|
||||
|
||||
if format != 'raw': # That's from API 1.9.0 but whatever
|
||||
if maxBitRate:
|
||||
try:
|
||||
maxBitRate = int(maxBitRate)
|
||||
except:
|
||||
return request.error_formatter(0, 'Invalid bitrate value')
|
||||
|
||||
if res.bitrate > maxBitRate:
|
||||
# TODO transcode
|
||||
pass
|
||||
if dst_bitrate > maxBitRate and maxBitRate != 0:
|
||||
do_transcoding = True
|
||||
dst_bitrate = maxBitRate
|
||||
|
||||
if format and format != res.suffix():
|
||||
# TODO transcode
|
||||
pass
|
||||
if format and format != src_suffix:
|
||||
do_transcoding = True
|
||||
dst_suffix = format
|
||||
dst_mimetype = scanner.get_mime(dst_suffix)
|
||||
|
||||
if do_transcoding:
|
||||
transcoder = config.get('transcoding', 'transcoder_{}_{}'.format(src_suffix, dst_suffix))
|
||||
decoder = config.get('transcoding', 'decoder_' + src_suffix) or config.get('transcoding', 'decoder')
|
||||
encoder = config.get('transcoding', 'encoder_' + dst_suffix) or config.get('transcoding', 'encoder')
|
||||
if not transcoder and (not decoder or not encoder):
|
||||
transcoder = config.get('transcoding', 'transcoder')
|
||||
if not transcoder:
|
||||
return request.error_formatter(0, 'No way to transcode from {} to {}'.format(src_suffix, dst_suffix))
|
||||
|
||||
transcoder, decoder, encoder = map(lambda x: prepare_transcoding_cmdline(x, res.path, src_suffix, dst_suffix, dst_bitrate), [ transcoder, decoder, encoder ])
|
||||
if transcoder:
|
||||
proc = subprocess.Popen(transcoder, stdout = subprocess.PIPE)
|
||||
else:
|
||||
dec_proc = subprocess.Popen(decoder, stdout = subprocess.PIPE)
|
||||
proc = subprocess.Popen(encoder, stdin = dec_proc.stdout, stdout = subprocess.PIPE)
|
||||
|
||||
def transcode():
|
||||
while True:
|
||||
data = proc.stdout.read(8192)
|
||||
if not data:
|
||||
break
|
||||
yield data
|
||||
proc.terminate()
|
||||
proc.wait()
|
||||
|
||||
response = Response(transcode(), mimetype = dst_mimetype)
|
||||
else:
|
||||
response = send_file(res.path)
|
||||
|
||||
# TODO handle estimateContentLength
|
||||
|
||||
res.play_count = res.play_count + 1
|
||||
res.last_play = now()
|
||||
@ -40,10 +87,7 @@ def stream_media():
|
||||
request.user.last_play_date = now()
|
||||
session.commit()
|
||||
|
||||
if estimateContentLength == 'true':
|
||||
return send_file(res.path), 200, { 'Content-Length': os.path.getsize(res.path) }
|
||||
|
||||
return send_file(res.path)
|
||||
return response
|
||||
|
||||
@app.route('/rest/download.view', methods = [ 'GET', 'POST' ])
|
||||
def download_media():
|
||||
|
11
scanner.py
11
scanner.py
@ -5,6 +5,17 @@ import time, mimetypes
|
||||
import mutagen
|
||||
import db
|
||||
|
||||
def get_mime(ext):
|
||||
ret = mimetypes.guess_type('dummy.' + ext, False)[0]
|
||||
if ret:
|
||||
return ret
|
||||
try:
|
||||
module = __import__('mutagen.' + ext, fromlist = [ 'Open' ])
|
||||
inst = module.Open()
|
||||
return inst.mime[0]
|
||||
except:
|
||||
return None
|
||||
|
||||
class Scanner:
|
||||
def __init__(self, session):
|
||||
self.__session = session
|
||||
|
Loading…
Reference in New Issue
Block a user