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

无中间服务器时如何从ReactJS直接上传视频至Azure Media Service

实现思路

核心逻辑:Azure Media Service(AMS)的视频资产底层存储本质是关联的Azure Blob存储容器,无需通过AMS管理SDK上传视频内容,仅需后端提前生成带临时写入权限的SAS令牌,前端直接将视频上传到对应Blob容器即可,全程视频流不经过服务端中转。
具体步骤:

  • 服务端(必须后端执行,避免AMS密钥泄露)预创建AMS空资产,调用存储接口生成该资产对应Blob容器的限时SAS令牌,仅开放写入权限,有效期建议控制在1~2小时
  • 服务端将SAS拼接后的上传地址返回给前端React组件
  • 前端使用Azure Blob存储客户端SDK,直接将视频文件上传到该SAS地址
  • 上传完成后前端通知服务端,由服务端触发AMS后续的编码、发布、流媒体处理等操作
代码示例

后端Node.js示例(仅在服务端运行,禁止放到前端)

首先安装依赖:

npm install @azure/arm-mediaservices @azure/identity @azure/storage-blob

核心代码:

const { AzureMediaServices } = require("@azure/arm-mediaservices");
const { DefaultAzureCredential } = require("@azure/identity");
const { BlobServiceClient, generateBlobSASQueryParameters, BlobSASPermissions } = require("@azure/storage-blob");

// AMS配置参数,存在服务端环境变量里
const subscriptionId = process.env.AZURE_SUBSCRIPTION_ID;
const resourceGroup = process.env.AZURE_RESOURCE_GROUP;
const amsAccountName = process.env.AZURE_MEDIA_ACCOUNT_NAME;
const storageAccountName = process.env.AZURE_STORAGE_ACCOUNT_NAME;
const storageAccountKey = process.env.AZURE_STORAGE_ACCOUNT_KEY;

async function getVideoUploadSas(fileName) {
  // 1. 初始化AMS客户端,创建空资产
  const credential = new DefaultAzureCredential();
  const amsClient = new AzureMediaServices(credential, subscriptionId);
  const asset = await amsClient.assets.createOrUpdate(resourceGroup, amsAccountName, `asset-${Date.now()}`, {});
  
  // 2. 生成资产对应Blob容器的SAS令牌
  const containerName = asset.container;
  const blobServiceClient = new BlobServiceClient(`https://${storageAccountName}.blob.core.windows.net`, credential);
  const containerClient = blobServiceClient.getContainerClient(containerName);
  
  const sasToken = generateBlobSASQueryParameters({
    containerName,
    blobName: fileName,
    permissions: BlobSASPermissions.parse("w"), // 仅开放写入权限
    expiresOn: new Date(Date.now() + 3600 * 1000), // 1小时有效期
  }, storageAccountKey).toString();
  
  // 3. 返回前端需要的上传地址和资产ID
  return {
    uploadUrl: `${containerClient.getBlockBlobClient(fileName).url}?${sasToken}`,
    assetId: asset.id
  };
}

前端React组件示例

安装客户端Blob SDK:

npm install @azure/storage-blob

核心代码:

import { useState } from 'react';
import { BlockBlobClient } from '@azure/storage-blob';

const VideoUploader = () => {
  const [uploadProgress, setUploadProgress] = useState(0);
  const [isUploading, setIsUploading] = useState(false);

  const handleFileSelect = async (e) => {
    const file = e.target.files[0];
    if (!file || file.type.indexOf('video/') === -1) return;
    
    setIsUploading(true);
    setUploadProgress(0);
    
    try {
      // 1. 从后端获取上传SAS地址
      const res = await fetch('/api/get-upload-sas', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ fileName: file.name })
      });
      const { uploadUrl, assetId } = await res.json();
      
      // 2. 直接上传到Blob存储
      const blockBlobClient = new BlockBlobClient(uploadUrl);
      await blockBlobClient.uploadData(file, {
        blockSize: 4 * 1024 * 1024, // 4MB分片,适合大视频
        concurrency: 5,
        onProgress: (progress) => {
          const percent = Math.round((progress.loadedBytes / file.size) * 100);
          setUploadProgress(percent);
        }
      });
      
      // 3. 通知后端上传完成,触发后续AMS处理
      await fetch('/api/on-upload-complete', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ assetId, fileName: file.name })
      });
      
      alert('视频上传成功');
    } catch (err) {
      console.error('上传失败', err);
      alert('上传失败,请重试');
    } finally {
      setIsUploading(false);
    }
  };

  return (
    <div>
      <input type="file" accept="video/*" onChange={handleFileSelect} disabled={isUploading} />
      {isUploading && <div>上传进度:{uploadProgress}%</div>}
    </div>
  );
};

export default VideoUploader;
注意事项
  • 必须在AMS关联的存储账户中配置CORS规则,允许前端域名的OPTIONS、PUT请求,否则会出现跨域错误
  • SAS令牌仅开放最小必要权限(仅写入)和最短有效期,避免被滥用
  • 大视频上传时SDK会自动处理断点续传、分片上传,无需额外开发
  • AMS的编码、发布、DRM配置等管理操作必须由后端调用AMS接口执行,禁止将AMS管理密钥暴露到前端

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 04:36:01