前提・実現したいこと
現在Express.jsを利用し、MYSQLに保存されたBLOBからHTMLのImageタグ or Videoタグのsrcにstreamを返すAPIを作成しております。
iPhoneで動画を撮影し、MYSQLに保存。動画の種類はmp4, movになります。
Videoの方に問題がありまして、PCブラウザ,iOSブラウザで動画の再生はできるのですが、Posterではない元々のサムネイルが表示されず、背景色かPosterを使用しないと見た目では表示されてないようになってしまいます。
どなたか解決策をご存知であればご教授いただけないでしょうか。
宜しくお願いします。
発生している問題・エラーメッセージ
Videoとして再生はできるが、Safariではmovが、iOSではmp4とmovがサムネイルが表示される。動画再生すれば表示される。
Chrome
Safari
Safari再生後
該当のソースコード
javascript
1const stream_buffers = require("stream-buffers"); 2 3router.get("/media", (req, res) => { 4 let media_data; 5 let content_type = ""; 6 let media_id = req.query.id; 7 let ranges = req.headers.range; 8 9 (async () => { 10 await Serviece 11 .getStream(media_id) 12 .then(function (res) { 13 media_data = res[0].data; 14 let file_name = res[0].file_name; 15 // ファイルの拡張子でContent-Typeを変更 16 if (file_name.match(/.(jpg|jpeg)$/)) { 17 content_type = "image/jpeg"; 18 } else if (file_name.match(/.gif$/)) { 19 content_type = "image/gif"; 20 } else if (file_name.match(/.png$/)) { 21 content_type = "image/png"; 22 } else if (file_name.match(/.mp4$/)) { 23 content_type = "video/mp4"; 24 } else if (file_name.match(/.MOV$/)) { 25 content_type = "video/quicktime"; 26 } else { 27 throw new Error("not media file"); 28 } 29 }) 30 .catch(function (err) { 31 console.error(err); 32 spocha.log.error(err); 33 media_data = err; 34 }); 35 36 if (ranges) { 37 let bytes = ranges.split("=")[1].split("-"); 38 let start = bytes[0] ? parseInt(bytes[0], 10) : bytes[0]; 39 let end = bytes[1] ? parseInt(bytes[1], 10) : bytes[1]; 40 console.log(`${ranges}/${media_data.length}`); 41 42 if (end == media_data.length -1 && start == 0) { 43 res.send(media_data, {"Content-Type": content_type }, 200); 44 } else if (start == 0 && (isNaN(end) || end == "")) { 45 res.send(media_data, {"Content-Type": content_type }, 200); 46 } else { 47 // Safari, iOSブラウザの場合は206対応 48 if (start != 0 && end == "") { 49 end = media_data.length - 1; 50 } 51 let content_length = end - start + 1; 52 let buffers = new stream_buffers.ReadableStreamBuffer({ 53 frequency: 1, 54 chunkSize: content_length, 55 }); 56 let byte_list = `bytes ${start}-${end}/${media_data.length}`; 57 let headers = { 58 "Content-Range": byte_list, 59 "Accept-Ranges": "bytes", 60 "Content-Length": content_length, 61 "Content-Type": content_type 62 }; 63 64 try { 65 buffers.put(media_data.slice(start, end)); 66 buffers.put(null); 67 res.writeHead(206, headers); 68 buffers.pipe(res); 69 } catch (err) { 70 console.error(err); 71 } finally { 72 buffers.stop(); 73 } 74 } 75 } else { 76 res.send(media_data, {"Content-Type": content_type }, 200); 77 } 78 })(); 79}); 80 81// 下記のようにvideoタグのsrcにAPIのURLを設定することで再生はできます。 82<video src="APIのURL">
試したこと
Safari, iOSはパーシャルコンテンツ対応が必要なためその対応はしております。(ここが怪しい?)
videoタグにplaysinline muted autoplayを設定し、自動再生されはするのですが、問題はサムネイル表示されないところにあります。poster等は使わず動画そのもののサムネイルを表示させたいです。
補足情報(FW/ツールのバージョンなど)
ここにより詳細な情報を記載してください。
node v12.8.0
npm v6.10.2
使用モジュール
stream-buffer v3.0.2
あなたの回答
tips
プレビュー