文章目录
- 一、简介
- 二、播放文件中视频
- [三、 播放TF卡中MP4视频文件](#三、 播放TF卡中MP4视频文件)
-
- 1.开启menuconfig配置
- 2.代码修改
-
- 1)添加TF卡挂载相关代码
- [2) mnt_init()函数修改](#2) mnt_init()函数修改)
- 3) mnt_init() 代码说明 mnt_init() 代码说明)
- 4)视频引用
- 四、现象
一、简介
黄山派播放视频例程
- 播放文件中的mp4视频
- 播放TF卡中视频
例程源码:本地视频播放
二、播放文件中视频
使用的例程默认播放 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.开始播放
