jQuery(function ($) { const dropzone = $("#qab-drop-area"); const fileInput = $("#qab-file-input"); const statusBox = $("#qab-upload-status"); const titleInput = $("#qab-video-title"); dropzone.on("click", () => fileInput.click()); fileInput.on("change", e => handleFiles(e.target.files)); dropzone.on("dragover", e => { e.preventDefault(); dropzone.addClass("qab-dragover"); }); dropzone.on("dragleave", e => { e.preventDefault(); dropzone.removeClass("qab-dragover"); }); dropzone.on("drop", e => { e.preventDefault(); dropzone.removeClass("qab-dragover"); handleFiles(e.originalEvent.dataTransfer.files); }); // ====================================================== // メイン // ====================================================== async function handleFiles(files) { if (!files.length) return; const file = files[0]; const title = titleInput.val() || file.name; statusBox.html(`

選択されたファイル: ${file.name}

`); // ① Lambda 署名URL & metadata 送信 const signed = await getPresignedUrl(file, title); if (!signed) return; statusBox.append("

署名URL取得完了 → アップロード開始

"); // ② S3 PUT const uploaded = await uploadToS3(file, signed.uploadUrl); if (uploaded) { statusBox.append("

S3アップロード完了

"); } else { statusBox.append("

アップロード失敗

"); } } // ====================================================== // 署名URL取得+metadata // ====================================================== async function getPresignedUrl(file, title) { try { const res = await fetch("https://your-lambda-url.amazonaws.com/s3/sign", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ filename: file.name, type: file.type, metadata: { title } }), }); if (!res.ok) { statusBox.append("

署名URLエラー

"); return null; } return await res.json(); } catch (err) { console.error(err); statusBox.append("

通信エラー

"); return null; } } // ====================================================== // S3 PUT // ====================================================== async function uploadToS3(file, uploadUrl) { return new Promise(resolve => { const xhr = new XMLHttpRequest(); xhr.open("PUT", uploadUrl, true); xhr.upload.onprogress = e => { if (e.lengthComputable) { const percent = Math.round((e.loaded / e.total) * 100); statusBox.append(`

${percent}% アップロード中...

`); } }; xhr.onload = () => resolve(xhr.status === 200); xhr.onerror = () => resolve(false); xhr.setRequestHeader("Content-Type", file.type); xhr.send(file); }); } }); Quebee キュエビー – 動画サイト
Miyuu、ワンマン・ライブで原点回帰「ライブの一体感が好き」【芸能動画】
 Miyuu、ワンマン・ライブで原点回帰「ライブの一体感が好き」【芸能動画】
Miyuu、ワンマン・ライブで原点回帰「ライブの一体感が好き」【芸能動画】