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

在Django中获取数据库存储视频的时长(已知title、URL、PK)

嘿,这个需求我刚好在项目里实现过,给你几个实用的方案,根据你的视频存储方式来选:

方案1:本地存储的视频(服务器Media目录下)

如果你的视频是存在Django的MEDIA_ROOT目录里的,推荐用moviepy库来读取视频元数据,操作起来很方便。

步骤:

  1. 先安装依赖:

    pip install moviepy
    

    (moviepy依赖FFmpeg,所以服务器上需要先安装FFmpeg,Ubuntu可以用apt install ffmpeg,CentOS用yum install ffmpeg)

  2. 在你的Video模型里加一个字段存储时长,然后在保存时自动计算:

    from django.db import models
    from moviepy.editor import VideoFileClip
    import os
    from django.conf import settings
    
    class Video(models.Model):
        title = models.CharField(max_length=200)
        video_file = models.FileField(upload_to='videos/')
        pk = models.AutoField(primary_key=True)
        duration = models.FloatField(null=True, blank=True)  # 单位:秒
    
        def save(self, *args, **kwargs):
            # 只有当视频文件更新且时长未设置时才计算
            if self.video_file and not self.duration:
                file_path = os.path.join(settings.MEDIA_ROOT, self.video_file.name)
                try:
                    with VideoFileClip(file_path) as clip:
                        self.duration = clip.duration  # 获取秒数
                except Exception as e:
                    print(f"计算时长失败: {str(e)}")
                    # 可以根据需求设置默认值或者抛出异常
            super().save(*args, **kwargs)
    
        def get_formatted_duration(self):
            # 把秒数转成 HH:MM:SS 的友好格式
            minutes, seconds = divmod(int(self.duration), 60)
            hours, minutes = divmod(minutes, 60)
            return f"{hours:02d}:{minutes:02d}:{seconds:02d}"
    

    这样每次上传视频时,时长就会自动存在duration字段里,之后直接调用video.get_formatted_duration()就能拿到格式化后的时长了。

方案2:远程URL的视频(第三方托管/外部链接)

如果视频是存在外部服务器(比如云存储、YouTube等),有两种方式:

方式A:调用第三方平台API(推荐)

比如YouTube可以用Data API获取视频时长,阿里云OSS可以用对象存储API获取文件元数据,这种方式最可靠,不会出现解析错误。具体API用法要看对应平台的文档,比如YouTube的API只需要传入视频ID就能拿到时长。

方式B:用FFmpeg解析远程URL

如果没有API可用,可以用FFmpeg直接读取远程视频的元数据,在Python里用subprocess执行命令:

import subprocess
import re

def get_remote_video_duration(video_url):
    try:
        # 执行FFmpeg命令,从stderr提取时长信息(FFmpeg默认把元数据输出到stderr)
        result = subprocess.run(
            ["ffmpeg", "-i", video_url],
            stderr=subprocess.PIPE,
            stdout=subprocess.PIPE,
            text=True
        )
        # 正则匹配Duration字段
        duration_match = re.search(r'Duration: (\d+:\d+:\d+\.\d+)', result.stderr)
        if duration_match:
            duration_str = duration_match.group(1)
            # 转成秒数
            hours, minutes, seconds = duration_str.split(':')
            total_seconds = int(hours)*3600 + int(minutes)*60 + float(seconds)
            return total_seconds
        return None
    except Exception as e:
        print(f"获取远程视频时长失败: {str(e)}")
        return None

注意:这种方式要考虑网络超时、URL权限(比如带签名的链接)问题,而且如果视频很大,FFmpeg会下载部分内容来解析,可能会有性能损耗,所以建议把计算后的时长存到数据库里,不要每次请求都计算。

额外建议
  • 优先把时长存到数据库:不管哪种方式,都建议在视频入库/更新时计算好时长并存到字段里,避免每次请求都重复计算,提升性能。
  • 异常处理:计算时长时一定要加异常捕获,避免因为视频损坏、路径错误等导致程序崩溃。
  • 格式转换:如果需要展示友好的时长格式(比如1小时23分),可以写个辅助方法来转换秒数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 06:53:52