黄山派播放TF卡MP4视频

文章目录

一、简介

黄山派播放视频例程

二、播放文件中视频

使用的例程默认播放 disk目录下的video_example.mp4 视频文件

  • 源视频文件内容为空文件,直接编译使用代码是不能播放出视频的
  • 使用自己的MP4文件替换disk目录下文件后编译下载即可播放
  • 代码默认没有开启TF卡的使用

三、 播放TF卡中MP4视频文件

这里不使用源代码中 SDIO (RT_USING_SDIO)相关的代码,使用前面学习的 SPI_TF (RT_USING_SPI_TF)

1.开启menuconfig配置




proj.conf文件内添加的配置

c 复制代码
CONFIG_BSP_USING_SPI1=y
CONFIG_BSP_SPI1_TX_USING_DMA=y
CONFIG_BSP_SPI1_RX_USING_DMA=y
CONFIG_RT_USING_SPI_MSD=y

2.代码修改

1)添加TF卡挂载相关代码

c 复制代码
#include "dfs_file.h"
#include "spi_msd.h"

#define FS_ROOT "root"   
#define FS_ROOT_PATH "/" 				//统一根目录路径为 '/'
#define FS_ROOT_OFFSET  0X00000000  	//起始地址
#define FS_ROOT_LEN     500*1024*1024   //500M

#define FS_BLOCK_SIZE 0x200


struct rt_device *fal_mtd_msd_device_create(char *name, long offset, long len)
{

    rt_device_t msd = rt_device_find("sd0");
    if (msd == NULL)
    {
        rt_kprintf("Error: the flash device name (sd0) is not found.\n");
        return NULL;
    }
    struct msd_device *msd_dev = (struct msd_device *)msd->user_data;

    struct msd_device *msd_file_dev = (struct msd_device *)rt_malloc(sizeof(struct msd_device));
    if (msd_file_dev)
    {
        msd_file_dev->parent.type        = RT_Device_Class_MTD;
#ifdef RT_USING_DEVICE_OPS
        msd_file_dev->parent.ops        = msd_dev->parent.ops;
#else
        msd_file_dev->parent.init       = msd_dev->parent.init;
        msd_file_dev->parent.open       = msd_dev->parent.open;
        msd_file_dev->parent.close      = msd_dev->parent.close;
        msd_file_dev->parent.read       = msd_dev->parent.read;
        msd_file_dev->parent.write      = msd_dev->parent.write;
        msd_file_dev->parent.control    = msd_dev->parent.control;
#endif
        msd_file_dev->offset            = offset;
        msd_file_dev->spi_device        = msd_dev->spi_device;
        msd_file_dev->geometry.bytes_per_sector = FS_BLOCK_SIZE;
        msd_file_dev->geometry.block_size = FS_BLOCK_SIZE;
        msd_file_dev->geometry.sector_count = len;

        rt_device_register(&msd_file_dev->parent, name,
                           RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
        rt_kprintf("fal_mtd_msd_device_create dev:sd0 part:%s offset:0x%x, size:0x%x\n", name, msd_file_dev->offset, msd_file_dev->geometry.sector_count);
        return RT_DEVICE(&msd_file_dev->parent);;
    }
    return NULL;
}


#include "dfs_file.h"
#include "spi_msd.h"

2) mnt_init()函数修改

c 复制代码
#ifndef FS_REGION_START_ADDR
    #error "Need to define file system start address!"
#endif
int mnt_init(void)
{
    char *name[2];

    rt_kprintf("===auto_mnt_init===\n");
    uint16_t time_out = 100;
    while (time_out --)
    {
        rt_thread_mdelay(30);
        if (rt_device_find("sd0"))
            break;
    }
    memset(name, 0, sizeof(name));
    name[0] = "sd0";
    fal_mtd_msd_device_create(FS_ROOT, FS_ROOT_OFFSET >> 9, FS_ROOT_LEN >> 9);

    /* 挂载 FS_ROOT,挂载路径 FS_ROOT_PATH,挂载类型 'elm' */
    if (dfs_mount(FS_ROOT, FS_ROOT_PATH, "elm", 0, 0) == 0) // fs exist
    {
        rt_kprintf("mount fs on flash to root success\n");
    }
    else
    {
        // auto mkfs, remove it if you want to mkfs manual
        rt_kprintf("mount fs on flash to root fail\n");
        if (dfs_mkfs("elm", FS_ROOT) == 0)//Format file system
        {
            rt_kprintf("make elm fs on flash sucess, mount again\n");
            if (dfs_mount(FS_ROOT, "/", "elm", 0, 0) == 0)
                rt_kprintf("mount fs on flash success\n");
            else
            {
                rt_kprintf("mount to fs on flash fail\n");
                return RT_ERROR;
            }
        }
        else
            rt_kprintf("dfs_mkfs elm flash fail\n");
    }

// #ifdef RT_USING_SDIO
//     //Waitting for SD Card detection done.
//     int sd_state = mmcsd_wait_cd_changed(3000);
//     if (MMCSD_HOST_PLUGED == sd_state)
//     {
//         rt_kprintf("SD-Card plug in\n");
//         name[0] = "sd0";
//     }
//     else
//     {
//         rt_kprintf("No SD-Card detected, state: %d\n", sd_state);
//     }
// #endif /* RT_USING_SDIO */


    name[1] = "flash0";
    register_mtd_device(FS_REGION_START_ADDR, FS_REGION_SIZE, name[1]);



    for (uint32_t i = 0; i < sizeof(name) / sizeof(name[0]); i++)
    {
        if (NULL == name[i]) continue;

        if (dfs_mount(name[i], "/", "elm", 0, 0) == 0) // fs exist
        {
            rt_kprintf("mount fs on %s to root success\n", name[i]);
            break;
        }
        else
        {
            rt_kprintf("mount fs on %s to root fail\n", name[i]);
        }
    }

    return RT_EOK;
}
INIT_ENV_EXPORT(mnt_init);

3) mnt_init() 代码说明

注册并将FS_ROOT挂载到'/'目录下,挂载类型为 'elm'

c 复制代码
    fal_mtd_msd_device_create(FS_ROOT, FS_ROOT_OFFSET >> 9, FS_ROOT_LEN >> 9);

    /* 挂载 FS_ROOT,挂载路径 FS_ROOT_PATH,挂载类型 'elm' */
    if (dfs_mount(FS_ROOT, FS_ROOT_PATH, "elm", 0, 0) == 0) // fs exist
    {
        rt_kprintf("mount fs on flash to root success\n");
    }
    else
    {
        // auto mkfs, remove it if you want to mkfs manual
        rt_kprintf("mount fs on flash to root fail\n");
        if (dfs_mkfs("elm", FS_ROOT) == 0)//Format file system
        {
            rt_kprintf("make elm fs on flash sucess, mount again\n");
            if (dfs_mount(FS_ROOT, "/", "elm", 0, 0) == 0)
                rt_kprintf("mount fs on flash success\n");
            else
            {
                rt_kprintf("mount to fs on flash fail\n");
                return RT_ERROR;
            }
        }
        else
            rt_kprintf("dfs_mkfs elm flash fail\n");
    }

源代码中的挂载文件系统函数

  • 如果根目录下已经挂载了文件系统后续文件系统则视为挂载失败
  • 所以使用了这里使用了SD卡中的视频文件后就不能使用代码中的视频文件了。
c 复制代码
    for (uint32_t i = 0; i < sizeof(name) / sizeof(name[0]); i++)
    {
        if (NULL == name[i]) continue;

        if (dfs_mount(name[i], "/", "elm", 0, 0) == 0) // fs exist
        {
            rt_kprintf("mount fs on %s to root success\n", name[i]);
            break;
        }
        else
        {
            rt_kprintf("mount fs on %s to root fail\n", name[i]);
        }
    }

4)视频引用

  • 将 VIDEO_SRC 数组下的文件名称改为SD卡下的存放的mp4文件名称,mp4文件存放在SD卡的根目录下。
  • 或者直接修改filename
    完成后编译下载即可播放TF卡中的视频文件



四、现象

正常即可播放TF卡中的视频文件

1.SD卡检测成功

2.成功挂载文件系统

3.打开失败

这里可以看到local.mp4是TF卡中没有的视频名称,所以自然也是打开失败,ret返回的值为-2(这里ret等于0说明成功获取到视频了,ret小于0就是失败了)

4.读取成功

可以看到,成功读取到视频 ret=0 而且会返回视频的数据信息


5.开始播放

相关推荐
xwz小王子14 分钟前
Science Robotics 封面论文:类人面部机器人的真实唇动学习
学习·机器人
ViiTor_AI21 分钟前
视频水印怎么去?8 款免费视频水印去除工具实测对比(不模糊)
人工智能·音视频
Tina Tang24 分钟前
Agentic AI学习笔记(3)
笔记·学习
ooo-p36 分钟前
FPGA学习篇——Verilog学习之“触摸按键控制LED灯”
学习·fpga开发
W.KN37 分钟前
AJAX 基础学习笔记
笔记·学习·ajax
啊我不会诶38 分钟前
Codeforces Round 1072 (Div. 3)补题
笔记·学习·算法
EverydayJoy^v^1 小时前
RH134学习进程——六.管理SELinux安全
linux·学习·安全·selinux
小手智联老徐1 小时前
Jetson Orin Nano 音频设置与开发之 DTS
linux·驱动开发·音视频
Aliex_git1 小时前
Git SSH 配置
笔记·git·学习·ssh
zyb11475824331 小时前
JVM的学习
jvm·python·学习