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

如何在dash.mpd文件中添加动态S3预签名URL?

解决方案:动态生成带S3预签名URL的DASH MPD文件

1. 初始MPD模板生成:预留BaseURL占位

使用python-ffmpeg-video-streaming生成MPD时,不要写死BaseURL,而是预留一个占位符(比如{{S3_PRESIGNED_BASE_URL}}),方便后续后端动态替换。

from ffmpeg_streaming import Formats, Dash

video_path = "input.mp4"
dash = Dash(video_path, Formats.h264())

# 自动生成多码率分片,设置占位符作为临时BaseURL
dash.auto_generate_representations()
dash.output("dash_template.mpd", base_url="{{S3_PRESIGNED_BASE_URL}}")

2. 后端认证与动态MPD生成

后端先完成用户认证,通过后实时生成S3预签名URL,读取模板MPD并替换占位符,最终返回给客户端。以下是Flask框架的示例:

import boto3
from flask import Flask, Response, request, abort
from botocore.config import Config

app = Flask(__name__)
# 初始化S3客户端(使用v4签名版本)
s3_client = boto3.client('s3', config=Config(signature_version='s3v4'))
S3_BUCKET = "your-video-bucket"
MPD_TEMPLATE_PATH = "dash_template.mpd"

@app.route('/stream/dash.mpd')
def serve_dash_mpd():
    # 1. 用户认证逻辑(示例:校验请求头的Authorization Token)
    auth_token = request.headers.get('Authorization')
    if not validate_auth_token(auth_token):
        abort(403, description="Unauthorized access")
    
    # 2. 生成S3预签名BaseURL(指向分片存储的S3前缀)
    # 设置有效期为30分钟,可根据安全需求调整
    presigned_url = s3_client.generate_presigned_url(
        'get_object',
        Params={'Bucket': S3_BUCKET, 'Key': 'videos/stream/'},
        ExpiresIn=1800,
        HttpMethod='GET'
    )
    # 处理预签名URL,保留前缀路径(匹配MPD中的相对分片路径)
    presigned_base_url = presigned_url.split('?')[0].rsplit('/', 1)[0] + '/'
    
    # 3. 读取模板并替换占位符
    with open(MPD_TEMPLATE_PATH, 'r') as f:
        mpd_content = f.read().replace("{{S3_PRESIGNED_BASE_URL}}", presigned_base_url)
    
    # 4. 返回动态MPD,设置正确的MIME类型和缓存控制
    response = Response(mpd_content, mimetype='application/dash+xml')
    response.headers['Cache-Control'] = 'no-cache'  # 禁止客户端缓存旧MPD
    return response

def validate_auth_token(token):
    # 实现你的认证逻辑(如JWT校验、数据库用户验证等)
    return token == "valid_user_token"

3. S3分片存储与路径一致性

生成的视频分片需上传到S3的指定路径(示例中为videos/stream/),确保MPD中的相对分片路径与S3对象路径完全匹配。上传示例代码:

import os
from glob import glob

def upload_shards_to_s3(shard_dir):
    for shard_path in glob(os.path.join(shard_dir, '*')):
        shard_key = f"videos/stream/{os.path.basename(shard_path)}"
        s3_client.upload_file(shard_path, S3_BUCKET, shard_key)

4. 预签名URL过期与自动更新

通过MPD的minimumUpdatePeriod参数控制播放器请求新MPD的频率,确保过期后自动获取带新预签名URL的MPD。生成模板时可添加该参数:

dash.output("dash_template.mpd", base_url="{{S3_PRESIGNED_BASE_URL}}", extra_params={
    'minimumUpdatePeriod': 'PT30M'  # 每30分钟请求一次新MPD
})

关键注意事项

  • 预签名有效期:建议设置15-60分钟,避免过长导致泄露风险。
  • S3权限控制:配置桶策略禁止公开访问,仅允许通过预签名URL或后端域名Referer访问:
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Deny",
                "Principal": "*",
                "Action": "s3:GetObject",
                "Resource": "arn:aws:s3:::your-video-bucket/*",
                "Condition": {
                    "StringNotLike": {
                        "aws:Referer": "https://your-backend-domain.com/*"
                    }
                }
            }
        ]
    }
    
  • MPD缓存:后端返回MPD时必须设置no-cache,防止客户端缓存旧的预签名URL。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 04:50:26