黄山派播放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.开始播放

相关推荐
Noushiki2 小时前
RabbitMQ 进阶 学习笔记2
笔记·学习·rabbitmq
Linux猿2 小时前
2025年中国AI学习平板市场洞察白皮书 | 附PDF
人工智能·学习·电脑·研报精选
阿猿收手吧!2 小时前
【音视频】MP4 文件结构详细解析
c++·音视频
赵长辉4 小时前
AGI-rag学习:ChromaDB使用1,txt类型文档【20251016课复习】
python·学习·llm·agi
赵长辉4 小时前
AGI-rag学习:ChromaDB使用2,json类型文档,问答类内容,【20251016课复习】
学习·agi
小小星球之旅11 小时前
CompletableFuture学习
java·开发语言·学习
盐焗西兰花11 小时前
鸿蒙学习实战之路-ArkTS循环渲染_ForEach使用指南
学习·华为·harmonyos
巧克力味的桃子11 小时前
单链表 - 有序插入并输出学习笔记
笔记·学习
坚持学习前端日记12 小时前
软件开发完整流程详解
学习·程序人生·职场和发展·创业创新