node.js - Safari 9 unable to play HTML5 Video with binary source? -
i'm working on web project using nodejs have video upload , player. video uploaded stored in mongodb in binary form, , when retrive via api localhost/api/media/:id :
/*getting media db in binary format*/ res.setheader('accept-ranges', 'bytes'); res.setheader('content-range', 'bytes=0-1/' + media.length); res.setheader('content-type', 'video/mp4'); res.setheader('cache-control', 'public,max-age=0'); res.send(media);
this work fine on chrome , firefox, using api give me html5 page video tag this:
<video controls="" autoplay="" name="media"> <source src="localhost/api/media/abcde" type="video/mp4"> </video>
which run fine on older safari 7. on safari 9 in particular it's not working , show media controller text "loading" , can never play video. try put same video file in localhost , access via localhost/test.mp4 , run ok in safari 9 there's no problem encoding of video. idea how make 1 work?
using gridfs can stream file client byte-range support:
var db var app = require('express')() var parserange = require('range-parser') var mongo = require('mongodb') var mongoclient = mongo.mongoclient var gridstore = mongo.gridstore var objectid = mongo.objectid function streamgridfile(req, res, next, gridfile) { res.setheader('accept-ranges', 'bytes') res.setheader('content-disposition', 'filename="' + req.params.file + '"') res.setheader('content-type', gridfile.contenttype) var ranges = parserange(gridfile.length, req.headers.range || '', { combine: true }) if (array.isarray(ranges) && ranges.length === 1 && ranges.type = 'bytes') { var type = ranges.type var start = ranges[0].start var end = ranges[0].end var total = end - start + 1 res.statuscode = 206 res.setheader('content-range', 'bytes ' + start + '-' + end + '/' + gridfile.length) res.setheader('content-length', total) return gridfile.seek(start, function() { var finished = false gridfile.stream(true).on('data', function (buff) { if (finished) return; var remaining = total total -= buff.length if (total <= 0) { res.end(buff.slice(0, remaining)) gridfile.close() finished = true } else { res.write(buff) } }).on('end', function () { if (finished) return; finished = true res.end() }).on('error', next) }) } else if (ranges === -1) { res.statuscode = 416 res.setheader('content-range', 'bytes */' + gridfile.length) return res.end() } else { res.statuscode = 200 res.setheader('content-length', gridfile.length) return gridfile.stream(true).pipe(res) } } app.get('/files/get/:file', function (req, res, next) { new gridstore(db, new objectid(req.params.file), null, 'r').open(function(err, gridfile) { return gridfile ? streamgridfile(req, res, next, gridfile) : res.send(404, 'not found') }) }) mongoclient.connect("mongodb://localhost/test", function(err, database) { if (err) throw err; db = database; })
Comments
Post a Comment