- ベストアンサー
Blobを使った画像と動画の識別方法
- WordPressでのファイルアップロード機能を検討中。
- 画像と動画の識別が課題であり、Data URIとBlob URLの表示方式について考察。
- 特に動画の表示をブラウザの対応によって避けるべきと述べている。
- みんなの回答 (19)
- 専門家の回答
質問者が選んだベストアンサー
・※別の方から頂いたアドバイス これは空にする方法ですよね。 私が修正した文字を出力する方法とは話しが違いますよね。 空にする方法は最も簡単な方法でいいと思います。 私個人的にはinnerHTMLがいいです。 別の方のアドバイスでなら1でいいと思います。 2と3の方法は、たぶんですが、名前、コメント、画像、スタンプを別々に削除していく方法で無駄な処理です。
その他の回答 (18)
- dell_OK
- ベストアンサー率13% (766/5720)
・動画をアップロードした際に画像として表示されているようです。 controls属性がなかったためのようです。 ・3つめのみアップロードされているようです。 終了タグ </video> がなかったためのようです。 いずれも修正しましたので見てください。 heightとwidthが同じ値で正方形に表示されていたので、 max-heightとmax-widthに変更しました。
補足
修正ありがとうございます。 1点だけ不安な点があるんですが、スマートフォンでページを開いたところ動画が表示されておりませんでした… GoogleとSafariどちらもシークレットモードではないのですが何か考えられる原因はありますでしょうか…?
- dell_OK
- ベストアンサー率13% (766/5720)
入力画面の内容を変数に保持して画面切り替えで使いまわすサンプルを作ってみました。 http://oksample.starfree.jp/%E8%B3%AA%E5%95%8F%E6%8E%B2%E7%A4%BA%E6%9D%BF/ こんな感じで動作すればよろしいのでしょうか。 JavaScriptのコードは直接見てみていただければと思います。 PHPのコードはこれでよければ改めて載せたいと思います。
補足
サンプルページありがとうございます、2点問題があるのですが、1点目は動画をアップロードした際に画像として表示されているようです。 2点目は名前:名前テスト3 コメント:コメントテスト3 と一緒に動画を3つアップロードしたのですが、3つめのみアップロードされているようです。
- dell_OK
- ベストアンサー率13% (766/5720)
・セッションで作成する方法の方が良いでしょうか…? サーバー側の処理(最初の送信からデータベースやファイルに保存するまで)はセッションでいいと思います。 クライアント側はサーバーからは何も受信せずにクライアント内でメモリ(変数)を使いまわせばいいと思います。ファイル削除については考えなくていいと思います。
お礼
Q.クライアント側はサーバーからは何も受信せずにクライアント内でメモリ(変数)を使いまわせばいいと思います。 A.こちらが最新の回答になります。 メモリ変数に記憶 セッションデータ Javascript で調べてみたところブラウザに情報を保存する方法という記事を見つけたのですが、 In-Memory という外部のサービスを使う方法しか見つけられず15MB以上の動画アップロードするための方法が少ないのではないかと心配です。 もしかするとレンタルサーバーのメモリーに一時的に保存するという事ではないかと思ったのですが、方法がわからず止まっております… 意味を完全に理解できていないのですが、クライアント内でメモリを使うというのはサーバー側でセッションデータをメモリ(変数)に一時的に記憶するという事でしょうか? メモリを使う方法と IndexedDB を一時ファイルとして使用する方法以外になるのですが、AJAXを使い保存する方法もあるとのアドバイスを別途頂きました。 ※参考サイト https://zenn.dev/kibe/articles/8ec80078e123a2 ※AJAXを使う方法 http://ashtarte.hotcom-web.com/utf8/smt.cgi?r+sara/&bid+00000789&tsn+00000789&bts+2023/11/20%2011%3A03%3A43Thread_00000789 ※セッションを使う画面還移するフォーム https://wandbox.org/permlink/Dp1Xqp400VTpr7wT
補足
回答ありがとうございます、 indexedDB についてもう少し詳しく調べてみようと頑張ってみたところ、一番近い形のコードを見つけることが出来ました。 こちらの方法でも組めるかもしれませんが、jQuery のバージョンアップで適応しないと直ぐに動かなくなるようです。 セッションで一度完成させてからこちらの方法でも考えてみようと思っております。 ※参考サイト https://stackoverflow.com/questions/52190185/how-to-upload-an-image-file-url-to-indexeddb-to-render-on-page ※最新コード https://wandbox.org/permlink/1I5SdoA0vN9w4IV4
- dell_OK
- ベストアンサー率13% (766/5720)
・IndexedDB を一時ファイルとして使用する方法を考えてみます。 ・file オブジェクトのままだとユーザーがファイルを削除した際に壊れてしまうので arrayBuffer として取り出しておくのが良いとのことです。 ファイル保存は考えずに、メモリ(変数)でいいような気がします。 arrayBufferの使い方はわかりませんが、これもメモリに覚えておく方法だと思いますよ。
補足
回答ありがとうございます、IndexedDB について調べてみたのですが、画像と動画の記事がなく、文字送信フォームについても明確な記事がないため難しいのではないかと思っております… 画像や動画を取得する方法がわからず、スタンプもどのように対応すべきか全く分からないのですが、 セッションで作成する方法の方が良いでしょうか…? ※blob.phpに調べたコードを書いております https://wandbox.org/permlink/hbSZgZB0lEGBtMAn ※jQuery で PDF を indexedDB APIでブラウザに保存 https://ptsv.jp/tag/javascript/ ※JavaScript IndexedDB の使いかた https://vbnettips.blog.shinobi.jp/javascript/javascript%20indexeddb%20%E3%81%AE%E4%BD%BF%E3%81%84%E6%96%B9%EF%BC%93 ※IndexedDBを使って、大きい動画や3Dモデルをローカルに保存 https://vr-lab.voyagegroup.com/entry/2017/06/26/120251 ※動画を保存 https://developers.microad.co.jp/entry/2018/08/08/174604
- dell_OK
- ベストアンサー率13% (766/5720)
質問されていた「画像と動画をどのように識別させるのか」についてですが、それはもともとやっている方法になると思います。 参考サイト(※Blobの項目について https://lab.syncer.jp/Web/JavaScript/Snippet/25/ )のコードに適用するとこんな感じになります。 ---- <body> <form> <input id="target" type="file" multiple> </form> <script> document.getElementById("target").addEventListener("change", function () { var fileList = this.files; for (var i = 0, l = fileList.length; l > i; i++) { var blobUrl = window.URL.createObjectURL(fileList[i]); const reader = new FileReader(); reader.onload = () => { var child = null; if (reader.result.indexOf("data:image/jpeg;base64,") === 0 || reader.result.indexOf("data:image/png;base64,") === 0) { child = document.createElement("img"); } else if (reader.result.indexOf("data:video/mp4;base64,") === 0) { child = document.createElement("video"); child.setAttribute("controls", null); } else if (reader.result.indexOf("data:application/pdf;base64,") === 0) { child = document.createElement("iframe"); } else { alert("対象外のファイルです"); } if (child !== null) { child.src = blobUrl; document.body.appendChild(child); } }; reader.readAsDataURL(fileList[i]); } }); </script> </body> ---- 大きな違いは child.src = blobUrl; だけです。 「Data URI で動画を表示する方法は対応ブラウザの関係で避けた方が良い」があるので、それに対応しただけな感じですね。 実行して開発モードで「Elements」を見ていただくとわかりますが、 DataURLを使うと、もともとは、 <img src="data:image/jpeg;base64,~~~"> とかだったのが、 <img src="blob:null/~~~"> のようになっています。 これをふまえると、Blobに何を覚えさせておくのか、と言うのは疑問になってきて、結局Blobでなくてもいいのではないか、と思えてきます。
補足
A.説明ありがとうございます、理解することが出来ました。 dell_ok さん以外にもお聞きしたのですが話がとびとびになっていたので、無料では使えない機能ではないかと疑っておりました。 Blob を使ってもセッションに保持する場合と変わらないようですね… これであればdell_okさんにアドバイス頂いたセッションを使う方法のみで良さそうです。 IndexedDB を一時ファイルとして使用する方法を考えてみます。 別途アドバイスを追加で頂いたのですが、file オブジェクトのままだとユーザーがファイルを削除した際に壊れてしまうので arrayBuffer として取り出しておくのが良いとのことです。 fileList = await Promise.all(formData.getAll('attach[]').map(file => file.arrayBuffer()));
- dell_OK
- ベストアンサー率13% (766/5720)
話しは少しそれるのと前にも聞いたかも知れないですが、アップロードファイルの選択コントロール(<input type="file">)を3個配置しているのはなぜですか。 コントロールは1個にして複数選択できるようにしてもいいような気がするので聞いてみました。
補足
回答ありがとうございます、ファイルアップロード機能を3つ付けたかったので、個数分 <input type="file"> が必要だと考えておりました。
- dell_OK
- ベストアンサー率13% (766/5720)
目的がわからなくなってきました。 Blobストレージは不要だと思います。 これまで言ってきた単なるBlobとは話しが違う気がします。 Blobで何をしようと思っていますか。
補足
回答ありがとうございます、Blob を使って value に値を保存するような形になるのでしょうか…? File オブジェクト(Blob のサブクラス)のリストのコードのみで良いとのアドバイスを頂きました。 var fileList = this.files ; Blobの項目についてのコードではだけで十分。 ※参考サイト https://developer.mozilla.org/ja/docs/Web/API/FormData/set ※Blobの項目について https://lab.syncer.jp/Web/JavaScript/Snippet/25/
- dell_OK
- ベストアンサー率13% (766/5720)
blob.phpはサムネイルを表示するためのものですよね。 アップロードはフォームを送信するのでこれは関係ないと思いますよ。
補足
回答ありがとうございます、Blob ストレージを使う場合有料なため月に20ドル近くかかるとのことで、初期のコストパフォーマンスから見ても得策ではなさそうに思えました… 調べた限り無料なものはないようですが、BLOBストレージとして使うという認識で合ってますでしょうか? ※参考サイト https://www.cloudflare.com/ja-jp/learning/cloud/what-is-blob-storage/ https://azure.microsoft.com/ja-jp/pricing/details/storage/page-blobs/
- 1
- 2
お礼
アドバイスありがとうございます、役割をよく理解できずに dell_ok さんにお聞きしておりました、申し訳ありません。 innerHTML を使う場合要素を空にする場合を除いて HTML のエスケープ処理を行い後の改修にて脆弱性が生まれる余地をなくすべきだとアドバイスを頂いておりました。 Document.createTextNode を使う方が良いかもしれませんね… 最新コードの146、149、153、233、236、240行目を変更いたしました。 要素を空にするコードではないかと勘違いしていたようで、初めに dell_ok さんにわからないところをお聞きしたほうが良かったです。 ※以前アドバイス頂いたコード ※元のコード function lengthCheck() { const left = this.dataset.maxlength - this.value.length; if (left >= 0) { this.nextElementSibling.innerHTML = 'あと<strong>' + left + '</strong>文字'; this.dataset.submit_disabled = this.value.length === 0; } else { this.nextElementSibling.innerHTML = '<strong>' + -left + '</strong>文字超過しています'; this.dataset.submit_disabled = true; } ↓ ※エスケープ処理 function escapeHTML(値) { _ var a = document.createElement('span'); _ a.textContent = 値; _ return a.innerHTML; } 要素.innerHTML = '<strong>' + escapeHTML(文字列) + '</strong>'; ※最新コード https://wandbox.org/permlink/ozofFRK7rkjCXV76 ______________________________ 質問の期限が切れてしまったため下記リンクに質問を立てさせていただきました。よろしくお願い致します。 ※新規質問 https://okwave.jp/qa/q10207678.html