12 视频播放 - 物联型
本文将介绍大彩视频的应用 -“从 U 盘复制视频到屏内”, 该功能由 LUA 脚本完成,本示例中, 屏内若有视频,会轮询播放,将准备好视频文件 U 盘插入,弹出提示框,提示“是否要复制”,若选择是,屏幕将所有视频选择一一复制
- 循环播放:可以轮询播放屏内的所有文件
- 文件检索:检索SD卡/U盘根目录下的MP4文件
- 拷贝文件:将检索到的文件,拷贝到屏内内存
本例程主要API函数,如下所示
- 播放视频:play_video(file,left,top,width,height)
- 停止播放:stop_video()
适用范围:物联型
例程下载链接:《物联型-视频播放应用》(点击跳转)
M系列/ 物联型视频播放相关对比,如下所示
M系列 | 物联型 | |
---|---|---|
播放API | play_video(file,left,top,width,height) | play_video(pathname,repeat) |
播放通知 | on_video_notify(msg,v1, v2) | 控件触控回调函数,对应的视频控件触发 |
图层关系 | 默认最顶层,会覆盖视频播放区域的其他控件 | 同一区域,根据控件层叠关系依次显示 |
路径盘符 | 屏内为‘3:/’,U盘/SD卡从回调函数获取 | 屏内为“A:/’,U盘/SD卡从回调函数获取 |
遍历方式 | 大彩API函数 | LUA 库函数 |
12.1 循环播放
画面配置
在教程 DEMO 的画面“main”(画面 ID0)中, 添加 3 个控件,分别为:
- 视频控件:用于播放视频
- 按钮控件:用于显示是否有 U 盘插入
- 文本控件:用于显示屏幕固件版本号,如下所示:
LUA 脚本
将所有需要播放的视频绝对路径放在一个表(数组)里面,当视频播放完,自动回调 function on_control_notify()函数,当判断是对应画面、对应视频控件触发时候,将表(数组)的索引 + 1,移动,指向下一个视频路径,则达到自动轮询播放视频的效果
--用户通过触摸修改控件后,执行此回调函数。
--点击按钮控件,修改文本控件、修改滑动条都会触发此事件。
function on_control_notify(screen,control,value)
if screen == sc_main
then
if control == 1
then
cur_video_paly_index = cur_video_paly_index + 1
if cur_video_paly_index > a_file_count
then
cur_video_paly_index = 1
end
stop_video()
play_video(a_file_names[cur_video_paly_index], 1)
elseif control == 6 and value == 0
then
change_screen(sc_udisk)
end
end
……
end
12.2 文件检索
当 U 盘插入时,自动调用系统函数 on_usb_inserted(dir), 此时,调用自定义的遍历函数 my_list_udisk(u_dir),递归方式遍历 u_dir 路径下的所有文件, 若为 mp4 文件,则将路径放在表(数组)中。 LUA脚本如下所示
--自定义函数: 获取扩展名
-- str 需要获取后缀名的字符串
function my_get_extension(str)
return str:match(".+%.(%w+)$")
end
-- 自定义函数,遍历 U 盘目录中的视频
function my_list_udisk(rootpath)
for entry in lfs.dir(rootpath)
do
--过滤 U 盘目录中的.和..
if entry ~= '.' and entry ~= '..'
then
local path = rootpath .. '/' .. entry
--获取指定路径的属性
local attr = lfs.attributes(path)
--非文件夹, 获取扩展名
if attr.mode ~= 'directory'
then
local ext = my_get_extension(path)
if ext == 'mp4'
then
u_file_count = u_file_count + 1
u_file_names[u_file_count] = path
end
--文件夹, 递归遍历下一级目录
else
my_list_udisk(path)
end
end
end
end
-- 系统回调函数,插入 U 盘自动回调
function on_usb_inserted(dir)
u_dir = dir
my_list_udisk(u_dir)
……
end
12.3 拷贝文件
本例程中, 将视频存储在 A 区中(A 区设置为 100M), 分配了 80M(LUA 代码中设置)的空间存放视频文件。实际应用中,需要根据工程编译后已使用空间,计算出剩余的空间,如下所示。本工程编译后, A 区使用了 1.96%的空间,剩下 98M 左右的空间大小
自定义函数 my_copy_udisk_to_adisk(),将提前遍历 U 盘的文件一一复制到屏内的存储中, 本例程中点击确定, 开始复制调用系统函数my_copy_udisk_to_adisk(),此时, 先判断需要复制的文件总大小是否会超过预先划分的大小, 然后删除 A 盘的文件,并将文件复制到屏内。当复制完毕后,遍历屏内的视频文件,在将视频路径放在表(数组)里,以便循环播放视频,代码如下所示
注意:视频复制过程不要断电和拔掉 U 盘
-- 获取文件大小
function my_raed_filesize(filename)
local fsize = false
local file = io.open(filename, "r")
if file
then
local current = file:seek()
fsize = file:seek("end")
file:seek("set", current)
io.close(file)
end
return fsize
end
-- 自定义函数,从 U 盘复制到屏内
function my_copy_udisk_to_adisk()
copy_file_allsize = 0
--计算要复制的文件总大小
for cnt = 1, u_file_count
do
copy_file_allsize = copy_file_allsize +
my_raed_filesize(u_file_names[cnt])
end
--需要复制文件的总大小 < 80M
if copy_file_allsize < a_disk_allszie
then
--删除 A 区中的视频
if a_file_count > 0
then
for cnt = 1, a_file_count
do
os.remove(a_file_names[cnt])
end
end
--开始复制
for cp_count = 1, u_file_count
do
cur_copy_filename= string.match(u_file_names[cp_count],".+/(.+)")
start_copy_file(u_file_names[cp_count],a_dir..string.match(u_file_names[cp_count],".+/(.+)"))
end
a_file_count = 0
a_file_names = {}
my_list_adisk(a_dir)
end
end
运行预览
编译工程,下载到实体屏中,将mp4文件拷贝到U盘根目录,插入U盘,依照提示完成拷贝过程,拔掉U盘进入自动播放