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

如何直接读取Google Drive视频二进制数据并打开播放?

问题:直接播放Google Drive API获取的视频二进制字节流

我通过Google Drive API获取到云端视频的二进制bytes数据,不想下载到本地,希望直接读取加载播放。已通过以下代码获取到文件内容:

...
def print_file_content(service, file_id):
    """Print a file's content.

    Args:
      service: Drive API service instance.
      file_id: ID of the file.

    Returns:
      File's content if successful, None otherwise.
    """
    try:
        # GET FILE'S DATA AND READ
        content = service.files().get_media(fileId=file_id).execute()
        < CODE - OPEN CONTENT/VIDEO >
        #
    except Exception as e:
        print('An error occurred: %s' % e)
print_file_content(service, file_id)

获取到的数据格式示例:

b'\x1aE\xdf\xa3\x01\x00\x00\x00\x00\x00\x00#B\x86\x81\x01B\xf7\x81\x01B\xf2\x81\x04B\xf3\x81\x08B\x82\x88matroskaB\x87\x81\x04B\x85\x81\x02\x18S\x80g\x01\x00\x00\x00\x00A\xffE\x11M\x9bt\xbeM\xbb\x8cS\xab\x84f\xa9I\x15S\xac\x82\x00\xdfM\xbb\x8cS\xab\x84k\xaeT\x16S\xac\x82\x01\'M\xbb\x8cS\xab\x84g\xc3T\x12S\xac\x82\x01\xafM...'

尝试过binascii、open(content,'rb')、io.BytesIO等方式均报错,使用python-vlc库也无法正常工作,求问如何直接从这些二进制字节数据打开并播放视频?


解决方案

方法1:用io.BytesIO配合pygame播放(适合简单MPEG视频)

将bytes数据包装为类文件对象,再通过pygame的Movie模块播放:

import io
import pygame

def print_file_content(service, file_id):
    try:
        content = service.files().get_media(fileId=file_id).execute()
        # 把二进制字节流包装成类文件对象
        video_io = io.BytesIO(content)
        
        # 初始化pygame并配置窗口
        pygame.init()
        pygame.mixer.quit()  # 关闭音频模块避免冲突
        video = pygame.movie.Movie(video_io)
        screen = pygame.display.set_mode(video.get_size())
        pygame.display.set_caption("GD Video Playback")
        
        # 设置视频显示表面并播放
        video_surface = pygame.Surface(video.get_size()).convert()
        video.set_display(video_surface)
        video.play()
        
        # 播放循环,处理退出事件
        running = True
        while running:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    running = False
            screen.blit(video_surface, (0, 0))
            pygame.display.update()
        
        # 清理资源
        video.stop()
        pygame.quit()
        
    except Exception as e:
        print('An error occurred: %s' % e)

注意:pygame.Movie仅支持MPEG格式视频,其他格式需更换方法。

方法2:用python-vlc配合自定义回调(支持多格式)

利用vlc的媒体回调接口,让vlc直接从字节流读取数据:

import vlc
import io

class ByteStreamReader:
    def __init__(self, byte_data):
        self.data = byte_data
        self.offset = 0

    def read_chunk(self, size):
        # 按vlc要求返回指定大小的字节块
        chunk = self.data[self.offset:self.offset + size]
        self.offset += size
        return chunk

def print_file_content(service, file_id):
    try:
        content = service.files().get_media(fileId=file_id).execute()
        stream_reader = ByteStreamReader(content)
        
        # 初始化vlc实例和媒体对象
        vlc_instance = vlc.Instance()
        # 注册回调函数,让vlc从我们的读取器获取数据
        media = vlc_instance.media_new_callbacks(
            lambda: None,  # 无需自定义open逻辑
            stream_reader.read_chunk,
            lambda: None,  # 简单场景无需seek回调
            lambda: None   # 无需自定义close逻辑
        )
        player = vlc_instance.media_player_new()
        player.set_media(media)
        
        # 启动播放
        player.play()
        
        # 保持程序运行直到播放结束或窗口关闭
        while player.is_playing():
            continue
        
        player.stop()
        
    except Exception as e:
        print('An error occurred: %s' % e)

注意:需确保系统已安装VLC播放器,且python-vlc版本与系统VLC版本兼容。

方法3:用ffpyplayer播放(兼容多数格式,支持帧处理)

基于FFmpeg的ffpyplayer库,适配绝大多数视频格式,还支持自定义帧处理:

import io
import pygame
from ffpyplayer.player import MediaPlayer

def print_file_content(service, file_id):
    try:
        content = service.files().get_media(fileId=file_id).execute()
        video_io = io.BytesIO(content)
        
        # 初始化媒体播放器
        player = MediaPlayer(video_io)
        display_screen = None
        
        while True:
            # 获取视频帧
            frame, status = player.get_frame()
            if status == 'eof':
                break  # 播放结束
            
            if frame is not None:
                img, timestamp = frame
                if display_screen is None:
                    # 初始化显示窗口
                    pygame.init()
                    display_screen = pygame.display.set_mode(img.get_size())
                    pygame.display.set_caption("GD Video via ffpyplayer")
                
                # 将ffpyplayer的帧转换为pygame可显示的格式
                pygame_surface = pygame.image.frombuffer(img.tobytes(), img.get_size(), 'RGB')
                display_screen.blit(pygame_surface, (0, 0))
                pygame.display.update()
            
            # 处理窗口退出事件
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    player.close_player()
                    pygame.quit()
                    return
        
        # 清理资源
        player.close_player()
        pygame.quit()
        
    except Exception as e:
        print('An error occurred: %s' % e)

需预先安装ffpyplayer和pygame库,适合需要对视频帧做额外处理的场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 21:30:25