Flet框架下能否使用本地资源播放MP4文件及实现方法
Flet框架下能否使用本地资源播放MP4文件及实现方法
嘿,你完全可以用Flet播放本地MP4文件的!官方文档里只放了HTTP资源的例子,只是因为本地路径依赖每个人的具体环境,不是不支持本地文件哦~我来给你讲讲具体的实现方法,以及排查你之前尝试失败的原因。
为什么你用./video/movie.mp4没生效?
大概率是路径匹配问题:相对路径是相对于你运行Python脚本时的工作目录,而不是脚本文件所在的目录。比如你在/Users/xxx目录下运行python Documents/flet_project/main.py,那脚本的工作目录是/Users/xxx,而不是/Users/xxx/Documents/flet_project,这时候./video/movie.mp4就会去/Users/xxx/video/movie.mp4找文件,自然找不到。
你可以先在代码里加一行打印确认工作目录:
import os print("当前工作目录:", os.getcwd())
三种实现本地MP4播放的方法
方法1:直接使用绝对路径(最直接,适合测试)
直接写视频文件的完整绝对路径,Mac上的格式比如/Users/xxx/Documents/flet_project/video/movie.mp4,这样Flet能精准找到文件:
sample_media = [ ft.VideoMedia( "/Users/xxx/Documents/flet_project/video/movie.mp4", extras={"artist": "本地测试视频", "album": "测试专辑"} ) ]
方法2:修正相对路径(适合项目内文件)
如果视频文件和脚本在同一目录结构下,确保运行脚本时的工作目录是脚本所在目录:
- 打开终端,先
cd到脚本所在的文件夹,再运行python main.py - 此时相对路径
./video/movie.mp4就会指向脚本目录下的video/movie.mp4
方法3:使用Flet的Assets资源管理(推荐,规范项目)
这是Flet推荐的资源管理方式,适合正式项目:
- 在项目根目录创建
assets文件夹,再建video子文件夹,把MP4文件放进去,结构如下:
你的项目文件夹/ ├── main.py └── assets/ └── video/ └── movie.mp4
- 修改
ft.app()的调用,指定assets目录:
ft.app(target=main, assets_dir="assets")
- 在
VideoMedia里使用/assets/video/movie.mp4作为路径:
sample_media = [ ft.VideoMedia( "/assets/video/movie.mp4", extras={"artist": "本地测试视频", "album": "测试专辑"} ) ]
排查问题的小技巧
如果还是无法播放,可以检查这几点:
- 路径是否正确:Mac系统路径区分大小写,注意文件名和文件夹名的大小写
- 文件是否存在:手动打开路径确认文件没被移动或删除
- 读取权限:确保当前用户有该视频文件的读取权限
修改后的完整代码示例
我帮你补充了代码里缺失的处理函数(不然运行会报错),并替换了本地路径的示例:
import random import flet as ft import os def main(page: ft.Page): print("当前工作目录:", os.getcwd()) # 打印工作目录,方便排查路径问题 page.theme_mode = ft.ThemeMode.LIGHT page.title = "TheEthicalVideo" page.window_always_on_top = True page.spacing = 20 page.horizontal_alignment = ft.CrossAxisAlignment.CENTER # 补充缺失的控制函数 def handle_stop(e): video.stop() print("Video.stop()") def handle_next(e): video.next() print("Video.next()") def handle_previous(e): video.previous() print("Video.previous()") def handle_seek(e): video.seek(10) print("Video.seek(10)") def handle_jump(e): video.jump_to_media(0) print("Jump to first media") def handle_add_media(e): new_media = ft.VideoMedia("./video/another_movie.mp4") video.playlist.append(new_media) video.update() print("Added new media") def handle_remove_media(e): if video.playlist: video.playlist.pop(random.randint(0, len(video.playlist)-1)) video.update() print("Removed media") def handle_volume_change(e): video.volume = int(e.control.value) video.update() print(f"Volume set to {video.volume}%") def handle_playback_rate_change(e): video.playback_rate = e.control.value video.update() print(f"Playback rate set to {video.playback_rate}X") def handle_pause(e): video.pause() print("Video.pause()") def handle_play_or_pause(e): video.play_or_pause() print("Video.play_or_pause()") def handle_play(e): video.play() print("Video.play()") # 使用本地绝对路径示例(替换成你的实际路径) sample_media = [ ft.VideoMedia( "/Users/xxx/Documents/flet_project/video/movie.mp4", extras={ "artist": "本地测试视频", "album": "测试专辑", }, ), ] # 若使用Assets方式,注释上面的sample_media,取消下面的注释并配置assets_dir # sample_media = [ # ft.VideoMedia( # "/assets/video/movie.mp4", # extras={ # "artist": "本地测试视频", # "album": "测试专辑", # }, # ), # ] page.add( video := ft.Video( expand=True, playlist=sample_media[0:2], playlist_mode=ft.PlaylistMode.LOOP, fill_color=ft.colors.BLUE_400, aspect_ratio=16/9, volume=100, autoplay=False, filter_quality=ft.FilterQuality.HIGH, muted=False, on_loaded=lambda e: print("Video loaded successfully!"), on_enter_fullscreen=lambda e: print("Video entered fullscreen!"), on_exit_fullscreen=lambda e: print("Video exited fullscreen!"), ), ft.Row( wrap=True, alignment=ft.MainAxisAlignment.CENTER, controls=[ ft.ElevatedButton("Play", on_click=handle_play), ft.ElevatedButton("Pause", on_click=handle_pause), ft.ElevatedButton("Play Or Pause", on_click=handle_play_or_pause), ft.ElevatedButton("Stop", on_click=handle_stop), ft.ElevatedButton("Next", on_click=handle_next), ft.ElevatedButton("Previous", on_click=handle_previous), ft.ElevatedButton("Seek s=10", on_click=handle_seek), ft.ElevatedButton("Jump to first Media", on_click=handle_jump), ft.ElevatedButton("Add Random Media", on_click=handle_add_media), ft.ElevatedButton("Remove Random Media", on_click=handle_remove_media), ], ), ft.Slider( min=0, value=100, max=100, label="Volume = {value}%", divisions=10, width=400, on_change=handle_volume_change, ), ft.Slider( min=1, value=1, max=3, label="PlaybackRate = {value}X", divisions=6, width=400, on_change=handle_playback_rate_change, ), ) # 若使用Assets方式,取消下面注释并注释上面的ft.app调用 # ft.app(target=main, assets_dir="assets") ft.app(target=main)
备注:内容来源于stack exchange,提问作者GotohRyo
相关产品推荐
相关产品推荐

