跳转至

MP4视频录制存储和上传

一、引言

本指南旨在指导用户如何使用 Air8101 开发板进行视频录制、将视频保存到 SD 卡以及通过 HTTP POST 请求上传到阿里云 OSS(对象存储服务)。

1.1 知识点概述

1. SD 卡文件系统:SD 卡通常使用 FAT32 文件系统,支持长文件名和大文件存储,是嵌入式系统中常用的存储介质。详细介绍可参考:SD 卡 - luatos@air8101 - 合宙模组资料中心

2. HTTP POST 请求:HTTP POST 是一种常用的网络请求方法,用于向服务器发送数据,适用于文件上传等场景。详细介绍可参考:HTTP - luatos@air8101 - 合宙模组资料中心

3. 阿里云 OSS:阿里云对象存储服务(OSS)是一种高可靠、高可用、高性能的云端存储服务,适用于存储和管理大量数据。详细介绍可参考:什么是对象存储 OSS_对象存储(OSS)-阿里云帮助中心

二、准备硬件环境

在深入介绍本功能示例之前,我们首先需要确保以下硬件环境的准备工作已经完成。

1. 参考:硬件环境清单,准备以及组装好基本硬件环境。

特别注意:如果你使用的 Air8101 开发板是“EVB_Air8101_B10”板,需要将 SD_3.3V 和 SWD3.3V 短接,如下图所示。

三、准备软件环境

在详细阐述本功能示例之前,我们需先精心筹备好以下软件环境。

1. Luatools 工具

2. 内核固件文件(底层 core 固件文件):LuatOS-SoC_V1003_Air8101_20250415_094624.soc(临时固件);

3. LuatOS 需要的脚本和资源文件

脚本和资源文件:https://gitee.com/openLuat/LuatOS-Air8101/tree/master/demo/mp4_video_upload

lib 脚本文件:使用 Luatools 烧录时,勾选“添加默认 lib”选项,使用默认 lib 脚本文件;

准备好软件环境之后,接下来查看如何烧录项目文件到 Air8101 开发板,将本篇文章中演示使用的项目文件烧录到 Air8101 开发板中。

四、常用 API 介绍

4.1 fatfs 相关 API 介绍

fatfs.mount(mode,mount_point, spiid_or_spidevice, spi_cs, spi_speed, power_pin, power_on_delay, auto_format)

挂载 fatfs

传入值参数说明

传入值参数
传入值类型
解释
mode
int
fatfs模式,可选fatfs.SPI,fatfs.SDIO,fatfs.RAM,fatfs.USB
mount_point
string
虚拟文件系统的挂载点, 默认是 /fatfs
spiid_or_spidevice
int
传入spi device指针,或者spi的id,或者sdio的id
spi_cs
int
片选脚的GPIO 号, spi模式有效,若前一个参数传的是spi device,这个参数就不需要传
spi_speed
int
SPI最高速度,默认10M, 若前2个参数传的是spi device,这个参数就不需要传
power_pin
int
TF卡电源控制脚,TF卡初始前先拉低复位再拉高,如果没有,或者是内置电源控制方式,这个参数就不需要传
power_on_delay
int
TF卡电源复位过程时间,单位ms,默认值是1
auto_format
bool
挂载失败是否尝试格式化,默认是true,即自动格式化. 本参数在2023.8.16添加

返回值参数说明

返回值类型
解释
bool
成功返回true, 否则返回nil或者false
string
失败的原因

例子

-- 方法1, 使用SPI模式
    local spiId = 2
    local result = spi.setup(
        spiId,--spi id
        255, -- 不使用默认CS脚
        0,--CPHA
        0,--CPOL
        8,--数据宽度
        400*1000  -- 初始化时使用较低的频率
    )
    local TF_CS = pin.PB3
    gpio.setup(TF_CS, 1)
    --fatfs.debug(1) -- 若挂载失败,可以尝试打开调试信息,查找原因
    -- 提醒, 若TF/SD模块带电平转换, 通常不支持10M以上的波特率!!
    fatfs.mount(fatfs.SPI,"SD", spiId, TF_CS, 24000000)
    local data, err = fatfs.getfree("SD")
    if data then
        log.info("fatfs", "getfree", json.encode(data))
    else
        log.info("fatfs", "err", err)
    end
    -- 往下的操作, 使用 io.open("/sd/xxx", "w+") 等io库的API就可以了

fatfs.unmount(mount_point)

取消挂载 fatfs

传入值参数说明

传入值参数
传入值类型
解释
mount_point
string
虚拟文件系统的挂载点, 默认是 fatfs,必须与fatfs.mount一致

返回值参数说明

返回值类型
解释
int
成功返回0, 否则返回失败码

例子

fatfs.mount("SD")

fatfs.getfree(mount_point)

获取可用空间信息

传入值参数说明

传入值参数
传入值类型
解释
mount_point
string
挂载点, 需要跟fatfs.mount传入的值一致

返回值参数说明

返回值类型
解释
table
若成功会返回table,否则返回nil
int
导致失败的底层返回值

例子

-- table包含的内容有
-- total_sectors 总扇区数量
-- free_sectors 空闲扇区数量
-- total_kb 总字节数,单位kb
-- free_kb 空闲字节数, 单位kb
-- 注意,当前扇区大小固定在512字节

    local data, err = fatfs.getfree("SD")
    if data then
        log.info("fatfs", "getfree", json.encode(data))
    else
        log.info("fatfs", "err", err)
    end

fatfs.debug(value)

设置调试模式

传入值参数说明

传入值参数
传入值类型
解释
value
bool
是否进入调试模式,true代表进入调试模式,增加调试日志

返回值参数说明

返回值类型
解释
nil
无返回值

例子

fatfs.debug(1) -- 设置true或者1都可以

4.2 camera 相关 API 介绍

camera.init(InitReg_or_cspi_id, cspi_speed, mode, is_msb, rx_bit, seq_type, is_ddr, only_y, scan_mode, w, h)

初始化摄像头

传入值参数说明

传入值参数
传入值类型
解释
InitReg_or_cspi_id
table/integer
如果是table,则是DVP摄像头的配置,同时忽略后续参数;如果是数字,则是camera spi总线序号
cspi_speed
int
camera spi总线速度
mode
int
camera spi模式,0~3
is_msb
int
字节的bit顺序是否是msb,0否1是
rx_bit
int
同时接收bit数,1,2,4
seq_type
int
byte序列,0~1
is_ddr
int
双边沿采样配置,0不启用,其他值根据实际SOC决定
only_y
int
只接收Y分量,0不启用,1启用,扫码必须启用,否则会失败
scan_mode
int
工作模式,camera.AUTO自动,camera.SCAN扫码
w
int
摄像头宽度
h
int
摄像头高度

返回值参数说明

返回值类型
解释
int/false
成功返回camera_id,失败返回false

例子

camera_id = camera.init(GC032A_InitReg)--屏幕输出rgb图像
--初始化后需要start才开始输出/扫码
camera.start(camera_id)--开始指定的camera

camera.start(id)

开始指定的 camera

传入值参数说明

传入值参数
传入值类型
解释
id
int
camera id,例如0

返回值参数说明

返回值类型
解释
boolean
成功返回true,否则返回false

例子

camera.start(0)

camera.stop(id)

停止指定的 camera

传入值参数说明

传入值参数
传入值类型
解释
id
int
camera id,例如0

返回值参数说明

返回值类型
解释
boolean
成功返回true,否则返回false

例子

camera.stop(0)

camera.close(id)

关闭指定的 camera,释放相应的 IO 资源

传入值参数说明

传入值参数
传入值类型
解释
id
int
camera id,例如0

返回值参数说明

返回值类型
解释
boolean
成功返回true,否则返回false

例子

camera.close(0)

camera.capture(id, save_path, quality, x, y, w, h)

camera 拍照,若与 sys.wait(timeout)搭配可实现视频录制功能

传入值参数说明

传入值参数
传入值类型
解释
id
int
camera id,例如0
save_path
string/zbuff/nil
save_path,文件保存路径,空则写在上次路径里,默认是/capture.jpg,如果是zbuff,则将图片保存在buff内不写入文件系统
quality
int
quality, jpeg压缩质量,1最差,占用空间小,3最高,占用空间最大而且费时间,默认1
x
int
x, 裁剪起始横坐标,从x列开始
y
int
y, 裁剪起始纵坐标,从y行开始
w
int
w, 裁剪后的宽度
h
int
h, 裁剪后的高度

返回值参数说明

返回值类型
解释
boolean
成功返回true,否则返回false,真正完成后通过camera.on设置的回调函数回调接收到的长度

例子

---------------------------------功能一:拍照----------------------------------------
------------------------------------------------------------------------------------
camera.capture(0)

---------------------------------功能二:视频录制------------------------------------
-----------------------------------------------------------------------------------
local camera_id = camera.USB -- 设置摄像头类型为USB摄像头

-- 配置USB摄像头参数
local usb_camera_table = {
    id = camera_id,      -- 摄像头ID
    sensor_width = 1280, -- 摄像头传感器宽度为1280像素
    sensor_height = 720, -- 摄像头传感器高度为720像素
    usb_port = 1         -- 设置USB摄像头端口为1,Air8101系列支持1、2、3、4端口
}

result = camera.init(usb_camera_table) -- 初始化指定的camera
log.info("摄像头初始化", result) -- 打印初始化结果
if(result == 0) then -- 0表示初始化成功
    camera.start(camera_id) -- 开始指定的camera
    --开始mp4录制
    camera.capture(camera_id, "/sd/abc.mp4", 1)
    sys.wait(20000) -- 录制时长
    --结束MP4录制
    camera.stop(camera_id) -- 停止指定的camera
    log.info("保存成功") -- 打印保存成功结果
end
camera.close(camera_id) -- 关闭指定的camera,释放相应的IO资源
log.info("摄像头关闭") -- 打印关闭摄像头结果
--------------------------------------------------------------------------------------

4.3 http 相关 API 介绍

httpplus.request(opts)

执行 HTTP 请求

传入值参数说明

传入值参数
传入值类型
解释
opts
table
请求参数,是一个table,最起码得有url属性

返回值参数说明

返回值类型
解释
int
响应码,服务器返回的状态码>=100, 若本地检测到错误,会返回<0的值
服务器正常响应时返回结果,
否则是错误信息或者nil

例子

-- 请求参数介绍
local opts = {
    url    = "https://httpbin.air32.cn/abc", -- 必选, 目标URL
    method = "POST", -- 可选,默认GET, 如果有body,files,forms参数,会设置成POST
    headers = {}, -- 可选,自定义的额外header
    files = {},   -- 可选,键值对的形式,文件上传,若存在本参数,会强制以multipart/form-data形式上传
    forms = {},   -- 可选,键值对的形式,表单参数,若存在本参数,如果不存在files,按application/x-www-form-urlencoded上传
    body  = "abc=123",-- 可选,自定义body参数, 字符串/zbuff/table均可, 但不能与files和forms同时存在
    debug = false,    -- 可选,打开调试日志,默认false
    try_ipv6 = false, -- 可选,是否优先尝试ipv6地址,默认是false
    adapter = nil,    -- 可选,网络适配器编号, 默认是自动选
    timeout = 30,     -- 可选,读取服务器响应的超时时间,单位秒,默认30
    bodyfile = "xxx"  -- 可选,直接把文件内容作为body上传, 优先级高于body参数
}

local code, resp = httpplus.request({url="https://httpbin.air32.cn/get"})
log.info("http", code)
-- 返回值resp的说明
-- 情况1, code >= 100 时, resp会是个table, 包含2个元素
if code >= 100 then
    -- headers, 是个table
    log.info("http", "headers", json.encode(resp.headers))
    -- body, 是个zbuff
    -- 通过query函数可以转为lua的string
    log.info("http", "headers", resp.body:query())
    -- 也可以通过uart.tx等支持zbuff的函数转发出去
    -- uart.tx(1, resp.body)
end

五、开通阿里云 OSS 服务流程介绍

5.1 注册阿里云平台

1. 访问官网:打开浏览器,输入阿里云官网地址 https://www.aliyun.com/,点击进入。

2. 开始注册:在阿里云官网首页右上角点击“注册”按钮,进行注册。

3. 填写注册信息:根据页面提示选择注册方式并填写相关信息。

4. 完成注册:根据自己选择的方式进行注册即可,下图为手机号注册成功后显示的页面。

5.2 完成实名认证

1. 登陆账户:点击阿里云官网右上角的“登录”按钮,自由选择登录方式进行登录操作。

2. 进入账号管理:点击右上角头像进入阿里云账号管理页面。

3. 选择账户认证:在左侧导航栏中点击“账户认证”,自由选择“个人认证”或者“企业认证”。

4. 完成认证:根据页面提示,完善认证信息。

5.3 开通阿里云 OSS 服务

1. 搜索对象存储 OSS:接着上一步操作,点击中上处的“搜索”,直接搜索“对象存储 OSS”。

2. 进入 OSS 产品页面:根据图中箭头提示点击“对象存储 OSS”,进入 OSS 产品页面。

3. 点击立即开通:在 OSS 产品页面根据箭头位置点击“立即开通”,然后根据页面提示完成开通即可。

4. 创建存储空间:在对象存储 OSS 页面,先点击左侧“Bucket 列表”按钮,然后点击“创建 Bucket”。除了“Bucket 名称”可以自定义命名外,其他选项按需选择或者保持默认。

5. 上传文件测试:完成创建后,通过上传文件操作进行测试,本文通过上传一张图片进行测试。

5.4 阿里云参数获取

1. 在对象存储界面获取 Bucket 域名。

2. 在此界面获取 阿里云 API 密钥(AccessKey ID 和 AccessKey Secret),测试时使用云账号 AccessKey,正常使用时还是建议用 RAM 用户 AccessKey。

3. 使用签名工具获取 Policy。

六、整体功能演示

6.1 功能概述

程序主要分为以下几个步骤:

1. 联网:通过 WiFi 连接到指定网络。

2. 挂载 SD 卡:初始化并挂载 SD 卡,用于后续存储视频文件。

3. 视频录制:初始化 USB 摄像头,开始录制视频,并保存到 SD 卡。

4. 视频上传:将录制好的视频文件保存到 SD 卡后通过 HTTP POST 请求上传到阿里云 OSS。

6.2 源码

源码获取链接:https://gitee.com/openLuat/LuatOS-Air8101/tree/master/demo/mp4_video_upload

6.3 演示

6.3.1 代码实现

main.lua

-- LuaTools需要PROJECT和VERSION这两个信息
PROJECT = "Air8101_VideoRecord_SDSave_OSSUpload"
VERSION = "1.0.0"

-- sys库是标配
_G.sys = require("sys")
httpplus = require "httpplus"

--[[
注意:B10开发板需要SD_3.3V和SWD3.3V短接
]]

-- 特别提醒, 由于FAT32是DOS时代的产物, 文件名超过8个字节是需要额外支持的(需要更大的ROM)
-- 例如 /sd/boottime 是合法文件名, 而/sd/boot_time就不是合法文件名, 需要启用长文件名支持.

local camera_id = camera.USB -- 设置摄像头类型为USB摄像头

-- 配置USB摄像头参数
local usb_camera_table = {
    id = camera_id,      -- 摄像头ID
    sensor_width = 1280, -- 摄像头传感器宽度为1280像素
    sensor_height = 720, -- 摄像头传感器高度为720像素
    usb_port = 1         -- 设置USB摄像头端口为1,Air8101系列支持1、2、3、4端口
}

-- 配置阿里云OSS请求参数(表单上传、签名)
-- 需要修改为自己的阿里云OSS参数
local opts = {
    url = "xxxxxxxx.oss-cn-hangzhou.aliyuncs.com", -- 必选, 目标URL
    method = "POST", -- 可选, 默认GET, 如果有body, files, forms参数, 会设置成POST
    headers = {}, -- 可选,自定义的额外header
    files = {file = "/sd/abc.mp4"}, -- 可选, 键值对的形式, 文件上传, 若存在本参数, 会强制以multipart/form-data形式上传
    forms = {
        key = "vedio/abc.mp4",
        policy = "xxxxxxxxxxx==",
        OSSAccessKeyId = "xxxxxxxxxxx",
        Signature = "xxxxxxxxxx="
    }, -- 可选,键值对的形式,表单参数,若存在本参数,如果不存在files,按application/x-www-form-urlencoded上传
}

-- 联网函数, 可自行删减
sys.taskInit(function()
    -----------------------------
    -- 统一联网函数, 可自行删减
    ----------------------------
    if wlan and wlan.connect then
        -- WiFi 联网, Air8101系列均支持
        -- 需要修改为自己的WiFi名称和密码,AP频段使用2.4Ghz频段,不支持5Ghz频段。
        local ssid = "HONOR_100_Pro"  -- WiFi名称
        local password = "12356789" -- WiFi密码
        log.info("WiFi", ssid, password)

        wlan.init() -- 初始化wlan
        wlan.connect(ssid, password, 1) -- 设备作为STA模式连接到指定的WiFi
        --等待WiFi联网结果,WiFi联网成功后,内核固件会产生一个"IP_READY"消息
        local result, data = sys.waitUntil("IP_READY") -- 等待"IP_READY"消息,并返回等待结果和数据
        log.info("wlan", "IP_READY", result, data)
    end
    log.info("已联网")
    sys.publish("net_ready") -- 发布一个"net_ready"消息,表示网络已就绪
end)

local rtos_bsp = rtos.bsp() -- 获取模组型号,此代码中应为 Air8101

-- 定义Air8101系列的SPI总线编号(spi_id)、片选引脚(pin_cs)以及文件系统类型(tp)
local function fatfs_spi_pin()

    if rtos_bsp == "Air8101" then
        return 0, 3, fatfs.SDIO
    else
        log.info("main", "bsp not support")
        return
    end
end

sys.taskInit(function()
    sys.wait(1000)
    -- fatfs.debug(1) -- 若挂载失败,可以尝试打开调试信息,查找原因

    -- 此为spi方式
    local spi_id, pin_cs,tp = fatfs_spi_pin()
    if tp and tp == fatfs.SPI then
        -- 仅SPI方式需要自行初始化spi, sdio不需要
        spi.setup(spi_id, nil, 0, 0, 8, 400 * 1000) -- 初始化SPI
        gpio.setup(pin_cs, 1) -- 设置pin_cs为输出模式
    end

    -- lua内存
    log.info("lua", rtos.meminfo())
    -- sys内存
    log.info("sys", rtos.meminfo("sys"))

-------------------------------挂载SD卡---------------------------------------------
-----------------------------------------------------------------------------------
    local mount_result = fatfs.mount(tp or fatfs.SPI, "/sd", spi_id, pin_cs, 24 * 1000 * 1000) -- 挂载SD卡
    log.info("fatfs", "mount", mount_result) -- 打印挂载结果
    local data, err = fatfs.getfree("/sd") -- 获取SD卡剩余空间信息
    if data then
        -- table: 若成功会返回table, 否则返回nil
        -- table 中包含 total_sectors(总扇区数量), free_sectors(空闲扇区数量), total_kb(总字节数,单位kb), free_kb(空闲字节数, 单位kb)
        log.info("fatfs", "getfree", json.encode(data))
    else
        -- err: 导致失败的底层返回值
        log.info("fatfs", "err", err)
    end

--------------------------------视频录制--------------------------------------------
-----------------------------------------------------------------------------------
    result = camera.init(usb_camera_table) -- 初始化指定的camera
    log.info("摄像头初始化", result) -- 打印初始化结果
    if(result == 0) then -- 0表示初始化成功
        camera.start(camera_id) -- 开始指定的camera
        --开始mp4录制
        camera.capture(camera_id, "/sd/abc.mp4", 1)
        sys.wait(20000) -- 录制时长
        --结束MP4录制
        camera.stop(camera_id) -- 停止指定的camera
        log.info("保存成功") -- 打印保存成功结果
    end
    camera.close(camera_id) -- 关闭指定的camera,释放相应的IO资源
    log.info("摄像头关闭") -- 打印关闭摄像头结果

--------------------------------阿里云OSS上传----------------------------------------
------------------------------------------------------------------------------------
    local code, resp = httpplus.request(opts) -- 执行HTTP请求
    log.info("http", code) -- 打印服务器返回的状态码
    -- 返回值resp的说明
    -- 情况1, code >= 100 时, resp会是个table, 包含2个元素
    if code ~= nil and code >= 100 then
        -- headers, 是个table
        log.info("http", "headers", json.encode(resp.headers))
        -- body, 是个zbuff
        -- 通过query函数可以转为lua的string
        log.info("http", "body", resp.body:query())
    end
end)

-- 用户代码已结束---------------------------------------------
-- 结尾总是这一句
sys.run()
-- sys.run()之后后面不要加任何语句!!!!!

6.3.2 程序烧录

1. 参考第二、三章节完成硬件与软件环境搭建。

2. 根据下图中步骤进行烧录程序

3. 根据下图中步骤将底层固件(core)文件和脚本代码(demo)文件烧录到 Air8101 开发板中。

6.3.3 现象复现

1. SD 卡挂载情况

2. 摄像头初始化情况

3. 视频录制情况

4. WiFi 联网情况

5. 视频上传情况

6.3.4 代码分析

1. 联网

-- 联网函数, 可自行删减
sys.taskInit(function()
    -----------------------------
    -- 统一联网函数, 可自行删减
    ----------------------------
    if wlan and wlan.connect then
        -- WiFi 联网, Air8101系列均支持
        -- 需要修改为自己的WiFi名称和密码,AP频段使用2.4Ghz频段,不支持5Ghz频段。
        local ssid = "HONOR_100_Pro"  -- WiFi名称
        local password = "12356789" -- WiFi密码
        log.info("WiFi", ssid, password)

        wlan.init() -- 初始化wlan
        wlan.connect(ssid, password, 1) -- 设备作为STA模式连接到指定的WiFi
        --等待WiFi联网结果,WiFi联网成功后,内核固件会产生一个"IP_READY"消息
        local result, data = sys.waitUntil("IP_READY") -- 等待"IP_READY"消息,并返回等待结果和数据
        log.info("wlan", "IP_READY", result, data)
    end
    log.info("已联网")
    sys.publish("net_ready") -- 发布一个"net_ready"消息,表示网络已就绪
end)
  • 替换 ssidpassword 为实际的 WiFi 名称和密码。
  • 程序将等待 WiFi 连接成功,并发布一个 net_ready 消息表示网络已就绪。

2. 挂载 SD 卡

local rtos_bsp = rtos.bsp() -- 获取模组型号,此代码中应为 Air8101

-- 定义Air8101系列的SPI总线编号(spi_id)、片选引脚(pin_cs)以及文件系统类型(tp)
local function fatfs_spi_pin()

    if rtos_bsp == "Air8101" then
        return 0, 3, fatfs.SDIO
    else
        log.info("main", "bsp not support")
        return
    end
end

sys.taskInit(function()
    -- fatfs.debug(1) -- 若挂载失败,可以尝试打开调试信息,查找原因

    -- 此为spi方式
    local spi_id, pin_cs,tp = fatfs_spi_pin()
    if tp and tp == fatfs.SPI then
        -- 仅SPI方式需要自行初始化spi, sdio不需要
        spi.setup(spi_id, nil, 0, 0, 8, 400 * 1000) -- 初始化SPI
        gpio.setup(pin_cs, 1) -- 设置pin_cs为输出模式
    end

    local mount_result = fatfs.mount(tp or fatfs.SPI, "/sd", spi_id, pin_cs, 24 * 1000 * 1000) -- 挂载SD卡
    log.info("fatfs", "mount", mount_result) -- 打印挂载结果
end)
  • 程序将初始化 SPI 总线并挂载 SD 卡到 /sd 目录。
  • 检查挂载结果,确保 SD 卡已正确挂载。

3. 视频录制

local camera_id = camera.USB -- 设置摄像头类型为USB摄像头

-- 配置USB摄像头参数
local usb_camera_table = {
    id = camera_id,      -- 摄像头ID
    sensor_width = 1280, -- 摄像头传感器宽度为1280像素
    sensor_height = 720, -- 摄像头传感器高度为720像素
    usb_port = 1         -- 设置USB摄像头端口为1,Air8101系列支持1、2、3、4端口
}

sys.taskInit(function()
    result = camera.init(usb_camera_table) -- 初始化指定的camera
    log.info("摄像头初始化", result) -- 打印初始化结果
    if(result == 0) then -- 0表示初始化成功
        camera.start(camera_id) -- 开始指定的camera
        --开始mp4录制
        camera.capture(camera_id, "/sd/abc.mp4", 1)
        sys.wait(20000) -- 录制时长
        --结束MP4录制
        camera.stop(camera_id) -- 停止指定的camera
        log.info("保存成功") -- 打印保存成功结果
    end
    camera.close(camera_id) -- 关闭指定的camera,释放相应的IO资源
    log.info("摄像头关闭") -- 打印关闭摄像头结果

end)
  • 初始化 USB 摄像头并开始录制视频,保存到 SD 卡的 /sd/abc.mp4 文件。
  • 录制时长为 20 秒,可根据需要调整 sys.wait 的参数。

4. 视频上传

可参考此链接熟悉各个参数,同时通过链接内每个参数的描述可以获取到对应的参数值,再自行根据选择添加到程序中对应位置。

-- 配置阿里云OSS请求参数(表单上传、签名)
local opts = {
    url = "xxxxxxxx.oss-cn-hangzhou.aliyuncs.com", -- 必选, 目标URL
    method = "POST", -- 可选, 默认GET, 如果有body, files, forms参数, 会设置成POST
    headers = {}, -- 可选,自定义的额外header
    files = {file = "/sd/abc.mp4"}, -- 可选, 键值对的形式, 文件上传, 若存在本参数, 会强制以multipart/form-data形式上传
    forms = {
        key = "vedio/abc.mp4",
        policy = "xxxxxxxxxxx==",
        OSSAccessKeyId = "xxxxxxxxxxx",
        Signature = "xxxxxxxxxx="
    }, -- 可选,键值对的形式,表单参数,若存在本参数,如果不存在files,按application/x-www-form-urlencoded上传
}

sys.taskInit(function()
    local code, resp = httpplus.request(opts) -- 执行HTTP请求
    log.info("http", code) -- 打印服务器返回的状态码
    -- 返回值resp的说明
    -- 情况1, code >= 100 时, resp会是个table, 包含2个元素
    if code ~= nil and code >= 100 then
        -- headers, 是个table
        log.info("http", "headers", json.encode(resp.headers))
        -- body, 是个zbuff
        -- 通过query函数可以转为lua的string
        log.info("http", "body", resp.body:query())
    end
end)
  • 配置阿里云 OSS 的上传参数,包括 URL 和表单参数。
  • 使用 httpplus.request 函数执行 HTTP POST 请求,上传视频文件到阿里云 OSS。
  • 打印服务器返回的状态码、headers 和 body 信息,以便调试和验证上传结果。

6.4 视频效果展示

视频链接:abc.mp4

七、注意事项

  • 确保 SD 卡已正确格式化为 FAT32 文件系统,且文件名不超过 8 个字节(如果需要支持长文件名,请参考相关文档进行配置)。
  • 根据实际情况调整 WiFi 名称、密码、阿里云 OSS 的 URL、AccessKeyId 和 Signature 等参数。
  • 录制视频时,请确保 SD 卡有足够的剩余空间。
  • 上传视频时,请确保网络连接稳定,以避免上传失败。

八、总结

通过该指南,用户可以使用 Air8101 开发板实现视频录制、保存到 SD 卡及通过 HTTP POST 上传到阿里云 OSS 的功能。在实际应用中,用户可能需要根据具体需求对程序进行进一步的修改和优化。