为了做这个东西网上搜了好久,还是没有找到有用的信息,最终想到看看自己用来把H264封装成MP4用的mp4v2库里有没有这个api,竟然还真找到了,读了一下也不是很难理解,只要再给MP4视频添加box用来盛放要添加的metadata信息就可以了。
照着MP4的详细解析看起来还是太费劲了,一直没搞明白box是个什么东西 -_-,后来看到这篇文章才明白过来。
直接贴代码吧。(是用海思3559A做的),不是海思的话应该一些地方改一下就可以了。
//kh_metadata.h
#ifndef __KH_METADATA_H__
#define __KH_METADATA_H__
#include "hi_type.h"
#include <mp4v2/mp4v2.h>
//#include "hi_common.h" //ema
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* End of #ifdef __cplusplus */
HI_S32 KH_Matadata_Init();
HI_S32 KH_Write_Metadata();
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* End of #ifdef __cplusplus */
#endif /* End of #ifndef __LOAD_BMP_H__*/
//kh_metadata.c
/******************************************************************************
Copyright (C), 2017, Hisilicon Tech. Co., Ltd.
******************************************************************************
File Name : kh_metadata.c
Version : Initial Draft
Author : Hisilicon multimedia software group
Created : 2017
Description :
******************************************************************************/
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* End of #ifdef __cplusplus */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <signal.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <dirent.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "sample_comm.h"
#include "kh_config.h"
#include "kh_mux.h"
#include "kh_metadata.h"
#define NUM_DATA 1
#define METADATA_CODE "khkh"
MP4FileHandle mp4_handle;
MP4ItmfItem *mp4_metadata;
uint8_t* datavalue[NUM_DATA];
//need to be called after MP4Create()
HI_S32 KH_Matadata_Init()
{
mp4_handle = KH_Get_MP4_FileHandle();
mp4_metadata = MP4ItmfItemAlloc(METADATA_CODE, NUM_DATA);
if (mp4_metadata == NULL)
{
SAMPLE_PRT("mp4_metadata alloc failed!\n");
return HI_FAILURE;
}
mp4_metadata->code = METADATA_CODE;
mp4_metadata->mean = "Metadata of KH";
mp4_metadata->name = "mtdt";
(mp4_metadata->dataList).size = NUM_DATA;
for (int i = 0; i < NUM_DATA; i++)
{
switch (i)
{
case 0:
datavalue[i] = "test";
(mp4_metadata->dataList).elements[i].typeSetIdentifier = 0;
(mp4_metadata->dataList).elements[i].typeCode = MP4_ITMF_BT_IMPLICIT;
(mp4_metadata->dataList).elements[i].locale = 0;
(mp4_metadata->dataList).elements[i].value = datavalue[i];
(mp4_metadata->dataList).elements[i].valueSize = strlen(datavalue[i]);
break;
default:
SAMPLE_PRT("Metadata message not up to number defined!\n");
return HI_FAILURE;
}
}
return HI_SUCCESS;
}
HI_S32 KH_Write_Metadata()
{
if (MP4ItmfAddItem(mp4_handle, mp4_metadata))
{
SAMPLE_PRT("write metadata success!\n");
return HI_SUCCESS;
}
else
return HI_FAILURE;
}
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* End of #ifdef __cplusplus */
我是从摄像头存储视频流的,在创建MP4文件后得到MP4FileHandle再用这个初始化就OK,然后可以在打开后写入视频流之前添加metadata,也可以在写完视频流之后写入,写完之后再Deinit就好了。如果是现成MP4文件,应该就不用创建了,直接打开文件,得到MP4FileHandle后初始化写入就行了。
存下来的MP4视频用文本编辑器打开就可以看到码流,在末尾附近搜索一下METADATA_CODE就能找到,我的METADATA_CODE是“khkh”,转换成十六进制就是6B68 6B68,找到后就可以看到metadata了