You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Python捕获前端图片/视频并上传至Azure Blob Storage求助

解决方案:前端捕获媒体文件并上传至Azure Blob Storage

一、前端捕获图片/视频文件

无需复杂框架,用原生JS就能实现媒体捕获:

图片捕获(两种方式)

  1. 从本地文件选择器获取
<input type="file" accept="image/*" id="imagePicker">
<script>
document.getElementById('imagePicker').addEventListener('change', (e) => {
  const imageFile = e.target.files[0];
  // 拿到File对象,可直接用于后续上传
  console.log('选中的图片:', imageFile);
});
</script>
  1. 摄像头拍照捕获
<video id="cameraPreview" autoplay style="width: 400px;"></video>
<button id="captureBtn">拍照</button>
<canvas id="imageCanvas" style="display: none;"></canvas>

<script>
// 开启摄像头
navigator.mediaDevices.getUserMedia({ video: true })
  .then(stream => {
    document.getElementById('cameraPreview').srcObject = stream;
  });

// 拍照转成File对象
document.getElementById('captureBtn').addEventListener('click', () => {
  const video = document.getElementById('cameraPreview');
  const canvas = document.getElementById('imageCanvas');
  canvas.width = video.videoWidth;
  canvas.height = video.videoHeight;
  canvas.getContext('2d').drawImage(video, 0, 0);
  
  canvas.toBlob(blob => {
    const capturedImage = new File([blob], 'camera-shot.jpg', { type: 'image/jpeg' });
    console.log('摄像头捕获的图片:', capturedImage);
    // 这里调用上传逻辑
  }, 'image/jpeg');
});
</script>

视频捕获(摄像头录制)

<video id="videoPreview" autoplay style="width: 400px;"></video>
<button id="startRecord">开始录制</button>
<button id="stopRecord">停止录制</button>

<script>
let mediaRecorder;
let recordedChunks = [];

// 开启摄像头+麦克风
navigator.mediaDevices.getUserMedia({ video: true, audio: true })
  .then(stream => {
    document.getElementById('videoPreview').srcObject = stream;
    mediaRecorder = new MediaRecorder(stream);
    
    mediaRecorder.ondataavailable = (e) => {
      if (e.data.size > 0) recordedChunks.push(e.data);
    };

    mediaRecorder.onstop = () => {
      const videoBlob = new Blob(recordedChunks, { type: 'video/webm' });
      const capturedVideo = new File([videoBlob], 'camera-recording.webm', { type: 'video/webm' });
      console.log('捕获的视频:', capturedVideo);
      recordedChunks = [];
      // 这里调用上传逻辑
    };
  });

document.getElementById('startRecord').addEventListener('click', () => mediaRecorder.start());
document.getElementById('stopRecord').addEventListener('click', () => mediaRecorder.stop());
</script>

二、简便上传至Azure Blob的方案(替代Flask)

方案1:前端直传(用Azure Storage JS SDK)

无需中转服务,前端通过SAS Token(后端生成,避免硬编码)直接上传:

<script src="https://aka.ms/azure-storage-js"></script>
<script>
async function uploadToBlob(file) {
  const accountName = '你的存储账户名';
  const containerName = '你的容器名';
  // SAS Token从你的Azure Function或后端接口获取,不要前端硬写
  const sasToken = '生成的SAS Token';

  const blobService = AzureStorage.Blob.createBlobServiceWithSas(
    `https://${accountName}.blob.core.windows.net`,
    sasToken
  );

  blobService.createBlockBlobFromBrowserFile(
    containerName,
    file.name,
    file,
    { contentSettings: { contentType: file.type } },
    (err, result) => {
      if (err) console.error('上传失败:', err);
      else console.log('上传成功,Blob地址:', result.url);
    }
  );
}
</script>

方案2:优化现有Azure Function接收上传

修改你的Azure Function,让它直接处理前端的FormData上传:

Azure Function(Node.js示例)

const { BlobServiceClient } = require('@azure/storage-blob');
const multer = require('multer');
const upload = multer();

module.exports = async function (context, req) {
  try {
    await upload.single('mediaFile')(req, {}, async () => {
      const file = req.file;
      if (!file) {
        context.res = { status: 400, body: '未上传文件' };
        return;
      }

      // 连接Blob存储
      const connStr = process.env.AZURE_STORAGE_CONNECTION_STRING;
      const blobServiceClient = BlobServiceClient.fromConnectionString(connStr);
      const containerClient = blobServiceClient.getContainerClient('你的容器名');
      
      // 上传文件
      const blobClient = containerClient.getBlockBlobClient(file.originalname);
      await blobClient.uploadData(file.buffer, { 
        blobHTTPHeaders: { blobContentType: file.mimetype } 
      });

      context.res = { status: 200, body: `上传成功:${blobClient.url}` };
    });
  } catch (err) {
    context.res = { status: 500, body: `上传失败:${err.message}` };
  }
};

前端调用Function上传

async function uploadViaFunction(file) {
  const formData = new FormData();
  formData.append('mediaFile', file);

  const res = await fetch('你的Azure Function URL', {
    method: 'POST',
    body: formData
  });

  const result = await res.json();
  console.log(result);
}

三、Flask失败的常见原因及修复

如果一定要用Flask,核心问题通常是:

  1. 未正确解析FormData:需用request.files获取文件
  2. 跨域问题:需安装flask-cors配置跨域
  3. 权限问题:确保Flask能读取Azure存储的连接字符串

Flask核心代码示例:

from flask import Flask, request
from flask_cors import CORS
from azure.storage.blob import BlobServiceClient

app = Flask(__name__)
CORS(app)

@app.route('/upload', methods=['POST'])
def upload():
    file = request.files.get('mediaFile')
    if not file:
        return '未上传文件', 400
    
    conn_str = '你的Azure存储连接字符串'
    blob_service_client = BlobServiceClient.from_connection_string(conn_str)
    container_client = blob_service_client.get_container_client('你的容器名')
    blob_client = container_client.get_blob_client(file.filename)
    
    blob_client.upload_blob(file, overwrite=True, content_settings={'content_type': file.content_type})
    return f'上传成功:{blob_client.url}', 200

if __name__ == '__main__':
    app.run(debug=True)

内容的提问来源于stack exchange,提问作者9combat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 02:52:47