Niedawno uruchomiono ten sam problem, ponieważ chcę wyświetlać moją bibliotekę w przeglądarkach. Niespodziewanie pomysł wysłania strumienia przez ffmpeg i dostarczania w locie działa całkiem dobrze. Podstawowym problemem było wsparcie poszukiwania ...
obserwuję, można znaleźć sniplets kodu w Pythonie stosując kolbę do rozwiązania problemu:
Musimy funkcję strumieniowo zawartość:
@app.route('/media/<path:path>.ogv')
def media_content_ogv(path):
d= os.path.abspath(os.path.join(config.media_folder, path))
if not os.path.isfile(d): abort(404)
start= request.args.get("start") or 0
def generate():
cmdline= list()
cmdline.append(config.ffmpeg)
cmdline.append("-i")
cmdline.append(d);
cmdline.append("-ss")
cmdline.append(str(start));
cmdline.extend(config.ffmpeg_args)
print cmdline
FNULL = open(os.devnull, 'w')
proc= subprocess.Popen(cmdline, stdout=subprocess.PIPE, stderr=FNULL)
try:
f= proc.stdout
byte = f.read(512)
while byte:
yield byte
byte = f.read(512)
finally:
proc.kill()
return Response(response=generate(),status=200,mimetype='video/ogg',headers={'Access-Control-Allow-Origin': '*', "Content-Type":"video/ogg","Content-Disposition":"inline","Content-Transfer-Enconding":"binary"})
Następnie musimy funkcję powrotu czas trwania:
@app.route('/media/<path:path>.js')
def media_content_js(path):
d= os.path.abspath(os.path.join(config.media_folder, path))
if not os.path.isfile(d): abort(404)
cmdline= list()
cmdline.append(config.ffmpeg)
cmdline.append("-i")
cmdline.append(d);
duration= -1
FNULL = open(os.devnull, 'w')
proc= subprocess.Popen(cmdline, stderr=subprocess.PIPE, stdout=FNULL)
try:
for line in iter(proc.stderr.readline,''):
line= line.rstrip()
#Duration: 00:00:45.13, start: 0.000000, bitrate: 302 kb/s
m = re.search('Duration: (..):(..):(..)\...', line)
if m is not None: duration= int(m.group(1)) * 3600 + int(m.group(2)) * 60 + int(m.group(3)) + 1
finally:
proc.kill()
return jsonify(duration=duration)
I wreszcie, siekać, że w HTML5 przy użyciu videojs:
<!DOCTYPE html>
<html>
<head>
<link href="//vjs.zencdn.net/4.5/video-js.css" rel="stylesheet">
<script src="//vjs.zencdn.net/4.5/video.js"></script>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
</head>
<body>
<video id="video" class="video-js vjs-default-skin" controls preload="auto" width="640" height="264">
</video>
<script>
var video= videojs('video');
video.src("media/testavi.avi.ogv");
// hack duration
video.duration= function() { return video.theDuration; };
video.start= 0;
video.oldCurrentTime= video.currentTime;
video.currentTime= function(time)
{
if(time == undefined)
{
return video.oldCurrentTime() + video.start;
}
console.log(time)
video.start= time;
video.oldCurrentTime(0);
video.src("media/testavi.avi.ogv?start=" + time);
video.play();
return this;
};
$.getJSON("media/testavi.avi.js", function(data)
{
video.theDuration= data.duration;
});
</script>
</body>
Przykład działania można znaleźć pod adresem https://github.com/derolf/transcoder.
dero
Co się stanie, jeśli 50 osób spróbuje obejrzeć Twój film w tym samym czasie (lub jeśli odświeżę 100 razy)? Transkodowanie w czasie rzeczywistym może działać na jednym wideo na stacji roboczej, ale podejrzewam, że jest to zbyt kosztowne, aby wykonać każde żądanie na serwerze. Może strategia "proszę czekać podczas konwertowania-potem-cache" zadziała? – Seth
Przechowywanie przekonwertowanego pliku jest tym, co już rozważałem w tym momencie. Ale [moja aplikacja] (http://github.com/TooTallNate/nTunes) ma być w każdym razie zablokowana dla kilku użytkowników, ponieważ otwarcie zezwalając na dostęp HTTP do całej biblioteki iTunes jest moim zdaniem niezbyt dobrym pomysłem . – TooTallNate
Chciałbym pójść z podejściem YouTube (sugestia Setha powyżej) - Zgaduję, że w pewnym momencie zadali to pytanie :) – Dolph