avplayer
音视频加载、播放控制和原生播放器。
脚本级音视频播放:加载远程/本地 URL、播放控制、跳转、调速与系统视频播放器。
边界:底层 AVPlayer 能力,适合纯脚本或非 AppUI 场景。AppUI 页面内嵌视频请用 AppUI 媒体控件 的VideoPlayer/PlayerController;短音效用 sound。切换媒体或离开页面时调用cleanup()。
#模块概览
| 项 | 说明 |
|---|---|
| 导入 | import avplayer |
| 适合做什么 | 播放 URL 流、脚本内播放控制、弹出系统视频播放器 |
| 调用时机 | 加载/播放在按钮回调;页面关闭时 cleanup() |
| 推荐顺序 | load(url) 成功 → play() → 控制 → cleanup() |
| 与 AppUI | 不要混用 avplayer 和 appui.VideoPlayer 控制同一媒体 |
#快速开始
下面脚本加载示例流、播放并清理:
已复制
import avplayer
url = (
"https://devstreaming-cdn.apple.com/videos/streaming/examples/"
"img_bipbop_adv_example_ts/master.m3u8"
)
if avplayer.load(url):
avplayer.set_volume(0.8)
avplayer.play()
print("时长:", avplayer.duration(), "秒")
print("当前:", avplayer.current_time(), "秒")
avplayer.pause()
avplayer.cleanup()
else:
print("媒体加载失败")
#AppUI 示例
脚本级播放控制演示;AppUI 内嵌视频请改用 PlayerController。
已复制
import appui
import avplayer
DEMO_URL = (
"https://devstreaming-cdn.apple.com/videos/streaming/examples/"
"img_bipbop_adv_example_ts/master.m3u8"
)
state = appui.State(
status="未加载",
position="0:00",
duration="—",
loaded=False,
)
def _format_time(seconds):
seconds = max(0, int(seconds))
return f"{seconds // 60}:{seconds % 60:02d}"
def load_media():
ok = avplayer.load(DEMO_URL)
state.loaded = ok
if ok:
dur = avplayer.duration()
state.batch_update(
status="已加载",
duration=_format_time(dur) if dur else "—",
position="0:00",
)
else:
state.batch_update(status="加载失败", loaded=False)
def play_media():
if not state.loaded:
state.status = "请先加载媒体"
return
avplayer.play()
state.status = "播放中"
def pause_media():
avplayer.pause()
state.status = "已暂停"
def refresh_position():
if not state.loaded:
return
state.position = _format_time(avplayer.current_time())
if avplayer.is_playing():
state.status = "播放中"
dur = avplayer.duration()
if dur:
state.duration = _format_time(dur)
def present_player():
if not state.loaded:
state.status = "请先加载媒体"
return
avplayer.present_video()
state.status = "已打开系统播放器"
def cleanup_media():
avplayer.cleanup()
state.batch_update(
loaded=False,
status="已清理",
position="0:00",
duration="—",
)
def body():
return appui.NavigationStack(
appui.Form([
appui.Section("媒体", [
appui.LabeledContent("状态", value=state.status),
appui.LabeledContent("进度", value=f"{state.position} / {state.duration}"),
]),
appui.Section("控制", [
appui.Button("加载示例流", action=load_media)
.button_style("bordered_prominent"),
appui.Button("播放", action=play_media),
appui.Button("暂停", action=pause_media),
appui.Button("刷新进度", action=refresh_position),
appui.Button("系统视频播放器", action=present_player),
appui.Button("清理资源", action=cleanup_media, role="destructive"),
], footer="需要网络;HLS 示例流仅供演示。"),
]).navigation_title("音视频播放")
)
appui.run(body, state=state)
#API 参考
#速查
| API | 作用 |
|---|---|
load(url) | 加载媒体 → bool |
play() / pause() / stop() | 播放控制 |
seek(seconds) | 跳转到指定秒数 |
duration() / current_time() | 总时长 / 当前位置(秒) |
is_playing() | 是否正在播放 |
set_volume(v) / set_rate(r) | 音量 / 倍速 |
present_video() | 弹出系统视频播放器 |
cleanup() | 释放资源 |
#模块级播放
已复制
import avplayer
if avplayer.load("https://example.com/audio.mp3"):
avplayer.set_volume(0.8)
avplayer.set_rate(1.0)
avplayer.play()
avplayer.seek(30)
avplayer.pause()
avplayer.cleanup()
| API | 说明 |
|---|---|
load(url) | 成功返回 True;失败不要调用播放 |
duration() | 未准备好时可能为 0 |
present_video() | 仅适合视频;音频不要用 |
cleanup() | 切换媒体或脚本结束前调用 |
#命名实例 Player
多路播放或脚本隔离时用 Player(id="main"):
已复制
player = avplayer.Player(id="main")
player.load(url)
player.play()
print(player.duration(), player.current_time())
player.cleanup()
方法与模块级函数相同,另支持 on_progress、on_end、on_error 等回调(高级场景)。
#与 AppUI 的分工
| 场景 | 推荐 |
|---|---|
| AppUI 页面内嵌视频 | appui.PlayerController + appui.VideoPlayer |
| 纯脚本 / 兼容旧代码 | avplayer |
| 短音效 | sound |
已复制
import appui
player = appui.PlayerController(id="main", url="https://example.com/video.m3u8")
def body():
return appui.VideoPlayer(player=player)
#常见错误
| 错误写法 | 后果 | 修正 |
|---|---|---|
未 load 就 play() | 无媒体可播 | 先检查 load(url) |
音频文件 present_video() | 界面不合适 | 仅视频使用 |
退出不 cleanup() | 资源占用 | 切换或关闭时清理 |
| AppUI 混用两套 API | 状态冲突 | 选一种方案 |
#相关文档
| 文档 | 用途 |
|---|---|
| AppUI 媒体控件 | 页面内 VideoPlayer |
| sound | 短音效与本地音频 |
| network | 下载媒体到本地 |
| 原生能力入口 | MiniApp 场景配方 |
#预期效果
运行示例后,界面应出现文档描述的目标结果;若与预期不符,先看「失败路径」并按返回值或日志排查。