如何直接读取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
相关产品推荐
相关产品推荐

