在 Django 中检查 base64 视频文件的音频和视频编解码器

回答 2 浏览 3975 2023-11-12

我目前正在开发一个 Django 项目,我需要检查 base64 编码视频文件的音频和视频编解码器。为了实现这一目标,我实现了一个函数,将 base64 字符串解码为二进制数据,然后尝试使用 MoviePy 加载视频剪辑。但是,在尝试运行代码时,我遇到了 AttributeError: '_io.BytesIO' object has no attribute 'endswith' 。

这是代码的相关部分:

import base64
from io import BytesIO
from moviepy.editor import VideoFileClip

def get_video_codec_info(base64_data):
    # Decode base64 string into binary data
    _format, _file_str = base64_data.split(";base64,")
    binary_data = base64.b64decode(_file_str)

    # Load the video clip using MoviePy
    clip = VideoFileClip(BytesIO(binary_data))

    # Get information about the video codec
    codec_info = {
        'video_codec': clip.video_codec,
        'audio_codec': clip.audio_codec,
    }

    return codec_info

错误发生在clip = VideoFileClip(BytesIO(binary_data))行,似乎与BytesIO的使用有关。我试图找到解决方案,但目前我陷入困境。

任何有关如何解决此问题或在 Django 中检查 Base64 编码视频文件的音频和视频编解码器的替代方法的建议将不胜感激。谢谢!

mahmudsajib 提问于2023-11-12
2 个回答
#1楼
得票数 2

您遇到的 AttributeError: '_io.BytesIO' object has no attribute 'endswith' 错误是因为 MoviePy 的 VideoFileClip 需要文件路径或 URL 作为其参数,但您传递的是 BytesIO 对象。要解决此问题,您可以从二进制数据创建一个临时文件,然后向VideoFileClip提供该临时文件的路径。这是您的代码的更新版本:

import base64
import tempfile
from moviepy.editor import VideoFileClip

def get_video_codec_info(base64_data):
    _format, _file_str = base64_data.split(";base64,")
    binary_data = base64.b64decode(_file_str)

    temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".mp4")
    temp_file.write(binary_data)
    temp_file.close()

    try:
        clip = VideoFileClip(temp_file.name)

        codec_info = {
            'video_codec': clip.video_codec,
            'audio_codec': clip.audio_codec,
        }
    finally:
        temp_file.unlink(temp_file.name)

    return codec_info
Ali Aban 提问于2023-11-12
#2楼
得票数 0

经过进一步调查和考虑,我找到了解决该问题的替代方案。该问题是由于在原始实现中使用 BytesIOMoviePy 引起的。为了解决这个问题,我建议采用一种不同的方法,即将 base64-decoded 二进制数据保存到临时文件,然后使用 ffprobe 收集视频 codec 信息。

import base64
import tempfile
import subprocess
import os
import json

def get_video_codec_info(base64_data):
    codec_names = []
    
    # Decode base64 string into binary data
    _, _file_str = base64_data.split(";base64,")
    binary_data = base64.b64decode(_file_str)

    # Save binary data to a temporary file
    with tempfile.NamedTemporaryFile(delete=False) as temp_file:
        temp_file.write(binary_data)
        temp_filename = temp_file.name

    try:
        # Run ffmpeg command to get video codec information
        command = ['ffprobe', '-v', 'error', '-show_entries', 'stream=codec_name:stream_tags=language', '-of', 'json', temp_filename]
        result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)

        if result.returncode == 0:
            # Try to parse the JSON output
            data = json.loads(result.stdout)
                
            # Iterate through streams and print information
            for stream in data['streams']:
                codec_names.append(stream.get('codec_name'))

    finally:
        # Clean up: delete the temporary file
        os.remove(temp_filename)
    
    return codec_names

这种方法使用 ffprobe 直接从视频文件中提取编解码器信息,绕过了 BytesIO 和 MoviePy 遇到的问题。确保您的系统上安装了 FFmpeg,因为它是 ffprobe 的先决条件。

mahmudsajib 提问于2023-11-12