Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
Z
ZLMediaKit
概览
Overview
Details
Activity
Cycle Analytics
版本库
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
问题
0
Issues
0
列表
Board
标记
里程碑
合并请求
0
Merge Requests
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
Snippets
成员
Collapse sidebar
Close sidebar
活动
图像
聊天
创建新问题
作业
提交
Issue Boards
Open sidebar
张翔宇
ZLMediaKit
Commits
124cce34
Commit
124cce34
authored
Aug 01, 2019
by
zqsong
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
mp4录制全部替换mp4v2为media-server
parent
7e92a0b7
显示空白字符变更
内嵌
并排
正在显示
4 个修改的文件
包含
196 行增加
和
204 行删除
+196
-204
3rdpart/media-server
+1
-1
CMakeLists.txt
+32
-11
src/MediaFile/Mp4Maker.cpp
+154
-177
src/MediaFile/Mp4Maker.h
+9
-15
没有找到文件。
media-server
@
a32fe104
Subproject commit
e399b93802610dcf574ff64bcb7677572cd028c
1
Subproject commit
a32fe104c0290bc01a7ee73d50b568e8d9ded93
1
CMakeLists.txt
查看文件 @
124cce34
...
@@ -2,6 +2,14 @@
...
@@ -2,6 +2,14 @@
cmake_minimum_required
(
VERSION 3.1.3
)
cmake_minimum_required
(
VERSION 3.1.3
)
#使能c++11
#使能c++11
set
(
CMAKE_CXX_STANDARD 11
)
set
(
CMAKE_CXX_STANDARD 11
)
SET
(
CMAKE_C_COMPILER aarch64-himix100-linux-gcc
)
SET
(
CMAKE_CXX_COMPILER aarch64-himix100-linux-g++
)
#SET(CMAKE_LINKER aarch64-himix100-linux-ld)
SET
(
CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER
)
SET
(
CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY
)
SET
(
CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY
)
#加载自定义模块
#加载自定义模块
set
(
CMAKE_MODULE_PATH
${
CMAKE_MODULE_PATH
}
"
${
PROJECT_SOURCE_DIR
}
/cmake"
)
set
(
CMAKE_MODULE_PATH
${
CMAKE_MODULE_PATH
}
"
${
PROJECT_SOURCE_DIR
}
/cmake"
)
...
@@ -14,6 +22,7 @@ set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
...
@@ -14,6 +22,7 @@ set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
set
(
ToolKit_Root
${
CMAKE_SOURCE_DIR
}
/3rdpart/ZLToolKit/src
)
set
(
ToolKit_Root
${
CMAKE_SOURCE_DIR
}
/3rdpart/ZLToolKit/src
)
set
(
MediaKit_Root
${
CMAKE_SOURCE_DIR
}
/src
)
set
(
MediaKit_Root
${
CMAKE_SOURCE_DIR
}
/src
)
#设置头文件目录
#设置头文件目录
INCLUDE_DIRECTORIES
(
${
ToolKit_Root
}
)
INCLUDE_DIRECTORIES
(
${
ToolKit_Root
}
)
INCLUDE_DIRECTORIES
(
${
MediaKit_Root
}
)
INCLUDE_DIRECTORIES
(
${
MediaKit_Root
}
)
...
@@ -32,11 +41,14 @@ endif ()
...
@@ -32,11 +41,14 @@ endif ()
set
(
ENABLE_HLS true
)
set
(
ENABLE_HLS true
)
set
(
ENABLE_OPENSSL true
)
set
(
ENABLE_OPENSSL true
)
set
(
ENABLE_MYSQL
tru
e
)
set
(
ENABLE_MYSQL
fals
e
)
set
(
ENABLE_MP4V2 true
)
set
(
ENABLE_MP4V2 true
)
set
(
ENABLE_FAAC true
)
set
(
ENABLE_FAAC false
)
set
(
ENABLE_X264 true
)
set
(
ENABLE_X264 false
)
set
(
MP4_H265RECORD true
)
set
(
ENABLE_MP4RECORD true
)
#添加两个静态库
#添加两个静态库
if
(
ENABLE_HLS
)
if
(
ENABLE_HLS
)
...
@@ -48,19 +60,28 @@ else()
...
@@ -48,19 +60,28 @@ else()
set
(
LINK_LIB_LIST zlmediakit zltoolkit
)
set
(
LINK_LIB_LIST zlmediakit zltoolkit
)
endif
()
endif
()
if
(
MP4_H265
RECORD
)
if
(
ENABLE_MP4
RECORD
)
message
(
STATUS
"
MP4_H265
RECORD defined"
)
message
(
STATUS
"
ENABLE_MP4
RECORD defined"
)
add_definitions
(
-D
MP4_H265
RECORD
)
add_definitions
(
-D
ENABLE_MP4
RECORD
)
set
(
MediaServer_Root
${
CMAKE_SOURCE_DIR
}
/3rdpart/media-server
)
set
(
MediaServer_Root
${
CMAKE_SOURCE_DIR
}
/3rdpart/media-server
)
list
(
APPEND LINK_LIB_LIST mov flv
)
list
(
APPEND LINK_LIB_LIST mov flv
)
endif
()
endif
()
set
(
OPENSSL_INCLUDE_DIR /nand/hi3559/openssl/include/
)
set
(
OPENSSL_LIBRARIES /nand/hi3559/openssl/lib/
)
#set(OPENSSL_CRYPTO_LIBRARIES /nand/hi3559/openssl/lib/libcrypto.so)
set
(
MP4V2_INCLUDE_DIR /nand/hi3559/mp4v2/include/
)
#set(MP4V2_LIBRARY /nand/hi3559/mp4v2/lib/libmp4v2.a)
set
(
MP4V2_LIBRARY /nand/hi3559/mp4v2/lib/libmp4v2.so
)
#查找openssl是否安装
#查找openssl是否安装
find_package
(
OpenSSL QUIET
)
find_package
(
OpenSSL QUIET
)
if
(
OPENSSL_FOUND AND ENABLE_OPENSSL
)
if
(
1
)
message
(
STATUS
"found library:
${
OPENSSL_LIBRARIES
}
,ENABLE_OPENSSL defined"
)
message
(
STATUS
"found library:
${
OPENSSL_LIBRARIES
}
,ENABLE_OPENSSL defined"
)
include_directories
(
${
OPENSSL_INCLUDE_DIR
}
)
include_directories
(
/nand/hi3559/openssl/include/
)
add_definitions
(
-DENABLE_OPENSSL
)
add_definitions
(
-DENABLE_OPENSSL
)
list
(
APPEND LINK_LIB_LIST
${
OPENSSL_LIBRARIES
}
)
list
(
APPEND LINK_LIB_LIST
/nand/hi3559/openssl/lib/libssl.so /nand/hi3559/openssl/lib/libcrypto.so
)
endif
()
endif
()
#查找mysql是否安装
#查找mysql是否安装
...
@@ -118,7 +139,7 @@ if(ENABLE_HLS)
...
@@ -118,7 +139,7 @@ if(ENABLE_HLS)
endif
(
WIN32
)
endif
(
WIN32
)
endif
()
endif
()
if
(
MP4_H265
RECORD
)
if
(
ENABLE_MP4
RECORD
)
aux_source_directory
(
${
MediaServer_Root
}
/libmov/include src_mov
)
aux_source_directory
(
${
MediaServer_Root
}
/libmov/include src_mov
)
aux_source_directory
(
${
MediaServer_Root
}
/libmov/source src_mov
)
aux_source_directory
(
${
MediaServer_Root
}
/libmov/source src_mov
)
include_directories
(
${
MediaServer_Root
}
/libmov/include
)
include_directories
(
${
MediaServer_Root
}
/libmov/include
)
...
...
src/MediaFile/Mp4Maker.cpp
查看文件 @
124cce34
...
@@ -24,7 +24,7 @@
...
@@ -24,7 +24,7 @@
* SOFTWARE.
* SOFTWARE.
*/
*/
#ifdef ENABLE_MP4
V2
#ifdef ENABLE_MP4
RECORD
#include <ctime>
#include <ctime>
#include <sys/stat.h>
#include <sys/stat.h>
#include "Common/config.h"
#include "Common/config.h"
...
@@ -40,10 +40,15 @@
...
@@ -40,10 +40,15 @@
#include "Thread/WorkThreadPool.h"
#include "Thread/WorkThreadPool.h"
#ifdef MP4_H265RECORD
#include "mov-buffer.h"
#include "mov-buffer.h"
#include "mov-format.h"
#include "mov-format.h"
using
namespace
toolkit
;
namespace
mediakit
{
#if defined(_WIN32) || defined(_WIN64)
#if defined(_WIN32) || defined(_WIN64)
#define fseek64 _fseeki64
#define fseek64 _fseeki64
#define ftell64 _ftelli64
#define ftell64 _ftelli64
...
@@ -52,43 +57,39 @@
...
@@ -52,43 +57,39 @@
#define ftell64 ftell
#define ftell64 ftell
#endif
#endif
static
int
mov
_file_r
ead
(
void
*
fp
,
void
*
data
,
uint64_t
bytes
)
static
int
mov
fileR
ead
(
void
*
fp
,
void
*
data
,
uint64_t
bytes
)
{
{
if
(
bytes
==
fread
(
data
,
1
,
bytes
,
(
FILE
*
)
fp
))
if
(
bytes
==
fread
(
data
,
1
,
bytes
,
(
FILE
*
)
fp
))
return
0
;
return
0
;
return
0
!=
ferror
((
FILE
*
)
fp
)
?
ferror
((
FILE
*
)
fp
)
:
-
1
/*EOF*/
;
return
0
!=
ferror
((
FILE
*
)
fp
)
?
ferror
((
FILE
*
)
fp
)
:
-
1
/*EOF*/
;
}
}
static
int
mov
_file_w
rite
(
void
*
fp
,
const
void
*
data
,
uint64_t
bytes
)
static
int
mov
fileW
rite
(
void
*
fp
,
const
void
*
data
,
uint64_t
bytes
)
{
{
return
bytes
==
fwrite
(
data
,
1
,
bytes
,
(
FILE
*
)
fp
)
?
0
:
ferror
((
FILE
*
)
fp
);
return
bytes
==
fwrite
(
data
,
1
,
bytes
,
(
FILE
*
)
fp
)
?
0
:
ferror
((
FILE
*
)
fp
);
}
}
static
int
mov
_file_s
eek
(
void
*
fp
,
uint64_t
offset
)
static
int
mov
fileS
eek
(
void
*
fp
,
uint64_t
offset
)
{
{
return
fseek64
((
FILE
*
)
fp
,
offset
,
SEEK_SET
);
return
fseek64
((
FILE
*
)
fp
,
offset
,
SEEK_SET
);
}
}
static
uint64_t
mov
_file_t
ell
(
void
*
fp
)
static
uint64_t
mov
fileT
ell
(
void
*
fp
)
{
{
return
ftell64
((
FILE
*
)
fp
);
return
ftell64
((
FILE
*
)
fp
);
}
}
const
struct
mov_buffer_t
*
mov
_file_b
uffer
(
void
)
const
struct
mov_buffer_t
*
mov
fileB
uffer
(
void
)
{
{
static
struct
mov_buffer_t
s_io
=
{
static
struct
mov_buffer_t
s_io
=
{
mov
_file_r
ead
,
mov
fileR
ead
,
mov
_file_w
rite
,
mov
fileW
rite
,
mov
_file_s
eek
,
mov
fileS
eek
,
mov
_file_t
ell
,
mov
fileT
ell
,
};
};
return
&
s_io
;
return
&
s_io
;
}
}
#endif
using
namespace
toolkit
;
namespace
mediakit
{
string
timeStr
(
const
char
*
fmt
)
{
string
timeStr
(
const
char
*
fmt
)
{
std
::
tm
tm_snapshot
;
std
::
tm
tm_snapshot
;
...
@@ -118,6 +119,11 @@ Mp4Maker::Mp4Maker(const string& strPath,
...
@@ -118,6 +119,11 @@ Mp4Maker::Mp4Maker(const string& strPath,
_info
.
strStreamId
=
strStreamId
;
_info
.
strStreamId
=
strStreamId
;
_info
.
strVhost
=
strVhost
;
_info
.
strVhost
=
strVhost
;
_info
.
strFolder
=
strPath
;
_info
.
strFolder
=
strPath
;
memset
(
&
_movH265info
,
0
,
sizeof
(
_movH265info
));
_movH265info
.
videoTrack
=
-
1
;
_movH265info
.
audioTrack
=
-
1
;
//----record 业务逻辑----//
//----record 业务逻辑----//
}
}
Mp4Maker
::~
Mp4Maker
()
{
Mp4Maker
::~
Mp4Maker
()
{
...
@@ -125,105 +131,140 @@ Mp4Maker::~Mp4Maker() {
...
@@ -125,105 +131,140 @@ Mp4Maker::~Mp4Maker() {
}
}
void
Mp4Maker
::
inputH264
(
void
*
pData
,
uint32_t
ui32Length
,
uint32_t
ui32TimeStamp
){
void
Mp4Maker
::
inputH264
(
void
*
pData
,
uint32_t
ui32Length
,
uint32_t
ui32TimeStamp
){
auto
iType
=
H264_TYPE
(((
uint8_t
*
)
pData
)[
0
]);
auto
iType
=
H264_TYPE
(((
uint8_t
*
)
pData
)[
4
]);
switch
(
iType
)
{
case
H264Frame
:
:
NAL_B_P
:
//P
if
(
H264Frame
::
NAL_B_P
<=
iType
&&
iType
<=
H264Frame
::
NAL_IDR
){
case
H264Frame
:
:
NAL_IDR
:
{
//IDR
if
(
_strLastVideo
.
size
())
{
int64_t
iTimeInc
=
(
int64_t
)
ui32TimeStamp
-
(
int64_t
)
_ui32LastVideoTime
;
int64_t
iTimeInc
=
(
int64_t
)
ui32TimeStamp
-
(
int64_t
)
_ui32LastVideoTime
;
iTimeInc
=
MAX
(
0
,
MIN
(
iTimeInc
,
500
));
iTimeInc
=
MAX
(
0
,
MIN
(
iTimeInc
,
500
));
if
(
iTimeInc
==
0
||
iTimeInc
==
500
){
if
(
(
iTimeInc
==
0
||
iTimeInc
==
500
)
&&
H264Frame
::
NAL_IDR
!=
iType
){
WarnL
<<
"abnormal time stamp increment:"
<<
ui32TimeStamp
<<
" "
<<
_ui32LastVideoTime
;
WarnL
<<
"abnormal time stamp increment:"
<<
ui32TimeStamp
<<
" "
<<
_ui32LastVideoTime
;
}
}
inputH264_l
((
char
*
)
_strLastVideo
.
data
(),
_strLastVideo
.
size
(),
iTimeInc
);
}
uint32_t
prefixe
=
htonl
(
ui32Length
);
if
(
_strLastVideo
.
size
()
){
_strLastVideo
.
assign
((
char
*
)
&
prefixe
,
4
);
//如果出现SPS PPS黏连的帧,那么在这里先处理
inputH264_l
((
char
*
)
_strLastVideo
.
data
(),
_strLastVideo
.
size
(),
_ui32LastVideoTime
);
_strLastVideo
=
""
;
}
inputH264_l
((
char
*
)
pData
,
ui32Length
,
ui32TimeStamp
);
_ui32LastVideoTime
=
ui32TimeStamp
;
}
else
{
//SPS PPS 进入等待组合为一帧
_strLastVideo
.
append
((
char
*
)
pData
,
ui32Length
);
_strLastVideo
.
append
((
char
*
)
pData
,
ui32Length
);
_ui32LastVideoTime
=
ui32TimeStamp
;
_ui32LastVideoTime
=
ui32TimeStamp
;
}
}
break
;
default
:
break
;
}
}
}
void
Mp4Maker
::
inputH265
(
void
*
pData
,
uint32_t
ui32Length
,
uint32_t
ui32TimeStamp
){
void
Mp4Maker
::
inputH265
(
void
*
pData
,
uint32_t
ui32Length
,
uint32_t
ui32TimeStamp
){
#ifdef MP4_H265RECORD
auto
iType
=
H265_TYPE
(((
uint8_t
*
)
pData
)[
4
]);
auto
iType
=
H265_TYPE
(((
uint8_t
*
)
pData
)[
4
]);
if
(
iType
<=
19
){
if
(
iType
<=
H265Frame
::
NAL_IDR_W_RADL
){
if
(
_strLastVideo
.
size
()
&&
iType
==
19
){
_strLastVideo
.
append
((
char
*
)
pData
,
ui32Length
);
int64_t
iTimeInc
=
(
int64_t
)
ui32TimeStamp
-
(
int64_t
)
_ui32LastVideoTime
;
inputH265_l
((
char
*
)
_strLastVideo
.
data
(),
_strLastVideo
.
size
(),
ui32TimeStamp
);
iTimeInc
=
MAX
(
0
,
MIN
(
iTimeInc
,
500
));
if
((
iTimeInc
==
0
||
iTimeInc
==
500
)
&&
H265Frame
::
NAL_IDR_W_RADL
!=
iType
){
WarnL
<<
"abnormal time stamp increment:"
<<
ui32TimeStamp
<<
" "
<<
_ui32LastVideoTime
;
}
if
(
_strLastVideo
.
size
()
){
//如果出现SPS PPS VPS黏连的帧,那么在这里先处理
inputH265_l
((
char
*
)
_strLastVideo
.
data
(),
_strLastVideo
.
size
(),
_ui32LastVideoTime
);
_strLastVideo
=
""
;
_strLastVideo
=
""
;
_ui32LastVideoTime
=
ui32TimeStamp
;
}
}
else
inputH265_l
((
char
*
)
pData
,
ui32Length
,
ui32TimeStamp
);
inputH265_l
((
char
*
)
pData
,
ui32Length
,
ui32TimeStamp
);
_ui32LastVideoTime
=
ui32TimeStamp
;
}
else
{
}
else
{
_strLastVideo
.
append
((
char
*
)
pData
,
ui32Length
);
_strLastVideo
.
append
((
char
*
)
pData
,
ui32Length
);
_ui32LastVideoTime
=
ui32TimeStamp
;
_ui32LastVideoTime
=
ui32TimeStamp
;
}
}
#endif
}
}
void
Mp4Maker
::
inputAAC
(
void
*
pData
,
uint32_t
ui32Length
,
uint32_t
ui32TimeStamp
){
void
Mp4Maker
::
inputAAC
(
void
*
pData
,
uint32_t
ui32Length
,
uint32_t
ui32TimeStamp
){
#ifdef MP4_H265RECORD
if
(
_h265Record
){
inputAAC_l
((
char
*
)
pData
,
ui32Length
,
ui32TimeStamp
);
}
else
#endif
{
if
(
_strLastAudio
.
size
())
{
int64_t
iTimeInc
=
(
int64_t
)
ui32TimeStamp
-
(
int64_t
)
_ui32LastAudioTime
;
int64_t
iTimeInc
=
(
int64_t
)
ui32TimeStamp
-
(
int64_t
)
_ui32LastAudioTime
;
iTimeInc
=
MAX
(
0
,
MIN
(
iTimeInc
,
500
));
iTimeInc
=
MAX
(
0
,
MIN
(
iTimeInc
,
500
));
if
(
iTimeInc
==
0
||
iTimeInc
==
500
){
if
(
iTimeInc
==
0
||
iTimeInc
==
500
){
WarnL
<<
"abnormal time stamp increment:"
<<
ui32TimeStamp
<<
" "
<<
_ui32LastAudioTime
;
WarnL
<<
"abnormal time stamp increment:"
<<
ui32TimeStamp
<<
" "
<<
_ui32LastAudioTime
;
}
}
inputAAC_l
((
char
*
)
_strLastAudio
.
data
(),
_strLastAudio
.
size
(),
iTimeInc
);
inputAAC_l
((
char
*
)
pData
,
ui32Length
,
ui32TimeStamp
);
}
_strLastAudio
.
assign
((
char
*
)
pData
,
ui32Length
);
_ui32LastAudioTime
=
ui32TimeStamp
;
_ui32LastAudioTime
=
ui32TimeStamp
;
}
}
}
void
Mp4Maker
::
inputH264_l
(
void
*
pData
,
uint32_t
ui32Length
,
uint32_t
ui32
Duration
)
{
void
Mp4Maker
::
inputH264_l
(
void
*
pData
,
uint32_t
ui32Length
,
uint32_t
ui32
TimeStamp
)
{
GET_CONFIG
(
uint32_t
,
recordSec
,
Record
::
kFileSecond
);
GET_CONFIG
(
uint32_t
,
recordSec
,
Record
::
kFileSecond
);
auto
iType
=
H264_TYPE
(((
uint8_t
*
)
pData
)[
4
]);
auto
iType
=
H264_TYPE
(((
uint8_t
*
)
pData
)[
4
]);
if
(
iType
==
H264Frame
::
NAL_IDR
&&
(
_hMp4
==
MP4_INVALID_FILE_HANDLE
||
_ticker
.
elapsedTime
()
>
recordSec
*
1000
)){
int32_t
compositionTime
;
if
(
iType
>=
H264Frame
::
NAL_IDR
&&
(
_movH265info
.
pMov
==
NULL
||
_ticker
.
elapsedTime
()
>
recordSec
*
1000
)){
//在I帧率处新建MP4文件
//在I帧率处新建MP4文件
//如果文件未创建或者文件超过10分钟则创建新文件
//如果文件未创建或者文件超过10分钟则创建新文件
//每一个录制的MP4文件时间戳都要从0开始
_startPts
=
ui32TimeStamp
;
createFile
();
createFile
();
}
}
if
(
_hVideo
!=
MP4_INVALID_TRACK_ID
)
{
MP4WriteSample
(
_hMp4
,
_hVideo
,
(
uint8_t
*
)
pData
,
ui32Length
,
ui32Duration
*
90
,
0
,
iType
==
5
);
char
*
pNualData
=
(
char
*
)
pData
;
if
(
_movH265info
.
pMov
!=
NULL
){
int
vcl
;
if
(
_movH265info
.
videoTrack
<
0
){
//解析解析SPS PPS,未添加track的时候执行
int
n
=
h264_annexbtomp4
(
&
_movH265info
.
avc
,
pData
,
ui32Length
,
_sBbuffer
,
sizeof
(
_sBbuffer
),
&
vcl
);
if
(
_movH265info
.
avc
.
nb_sps
<
1
||
_movH265info
.
avc
.
nb_pps
<
1
){
return
;
// waiting for sps/pps
}
uint8_t
sExtraData
[
64
*
1024
];
int
extraDataSize
=
mpeg4_avc_decoder_configuration_record_save
(
&
_movH265info
.
avc
,
sExtraData
,
sizeof
(
sExtraData
));
if
(
extraDataSize
<=
0
){
// invalid HVCC
return
;
}
}
// TODO: waiting for key frame ???
_movH265info
.
videoTrack
=
mov_writer_add_video
(
_movH265info
.
pMov
,
MOV_OBJECT_H264
,
_movH265info
.
width
,
_movH265info
.
height
,
sExtraData
,
extraDataSize
);
return
;
}
if
(
iType
<=
H264Frame
::
NAL_IDR
){
uint8_t
*
ptr
=
(
uint8_t
*
)
pData
;
ptr
[
0
]
=
(
uint8_t
)((
ui32Length
-
4
>>
24
)
&
0xFF
);
ptr
[
1
]
=
(
uint8_t
)((
ui32Length
-
4
>>
16
)
&
0xFF
);
ptr
[
2
]
=
(
uint8_t
)((
ui32Length
-
4
>>
8
)
&
0xFF
);
ptr
[
3
]
=
(
uint8_t
)((
ui32Length
-
4
>>
0
)
&
0xFF
);
uint32_t
ui32Pts
=
ui32TimeStamp
<
_movH265info
.
startPts
?
0
:
ui32TimeStamp
-
_movH265info
.
startPts
;
mov_writer_write
(
_movH265info
.
pMov
,
_movH265info
.
videoTrack
,
pData
,
ui32Length
,
ui32Pts
,
ui32Pts
,
iType
==
H264Frame
::
NAL_IDR
?
MOV_AV_FLAG_KEYFREAME
:
0
);
}
}
}
}
void
Mp4Maker
::
inputH265_l
(
void
*
pData
,
uint32_t
ui32Length
,
uint32_t
ui32TimeStamp
)
{
void
Mp4Maker
::
inputH265_l
(
void
*
pData
,
uint32_t
ui32Length
,
uint32_t
ui32TimeStamp
)
{
GET_CONFIG
(
uint32_t
,
recordSec
,
Record
::
kFileSecond
);
GET_CONFIG
(
uint32_t
,
recordSec
,
Record
::
kFileSecond
);
#ifdef MP4_H265RECORD
int32_t
compositionTime
;
int32_t
compositionTime
;
auto
iType
=
H265_TYPE
(((
uint8_t
*
)
pData
)[
4
]);
auto
iType
=
H265_TYPE
(((
uint8_t
*
)
pData
)[
4
]);
if
(
iType
>=
H265Frame
::
NAL_IDR_W_RADL
&&
(
_movH265info
.
pMov
==
NULL
||
_ticker
.
elapsedTime
()
>
recordSec
*
1000
)){
if
(
iType
>=
H265Frame
::
NAL_IDR_W_RADL
&&
(
_movH265info
.
pMov
==
NULL
||
_ticker
.
elapsedTime
()
>
recordSec
*
1000
)){
//在I帧率处新建MP4文件
//如果文件未创建或者文件超过10分钟则创建新文件
_h265Record
=
1
;
_h265Record
=
1
;
//每一个录制的MP4文件时间戳都要从0开始
_startPts
=
ui32TimeStamp
;
//在I帧率处新建MP4文件
//如果文件未创建或者文件超过最长时间则创建新文件
createFile
();
createFile
();
}
}
char
*
pNualData
=
(
char
*
)
pData
;
char
*
pNualData
=
(
char
*
)
pData
;
if
(
/*iType <= 31 && */
_movH265info
.
pMov
!=
NULL
){
if
(
_movH265info
.
pMov
!=
NULL
){
int
vcl
;
int
vcl
;
//media-server新版的api使用h265_annexbtomp4
//int n = h265_annexbtomp4(&_movH265info.hevc, pData, ui32Length, _sBbuffer, sizeof(_sBbuffer), &vcl);
int
n
=
hevc_annexbtomp4
(
&
_movH265info
.
hevc
,
pData
,
ui32Length
,
_sBbuffer
,
sizeof
(
_sBbuffer
));
if
(
_movH265info
.
videoTrack
<
0
){
if
(
_movH265info
.
videoTrack
<
0
){
//解析解析VPS SPS PPS,未添加track的时候执行
int
n
=
h265_annexbtomp4
(
&
_movH265info
.
hevc
,
pData
,
ui32Length
,
_sBbuffer
,
sizeof
(
_sBbuffer
),
&
vcl
);
if
(
_movH265info
.
hevc
.
numOfArrays
<
1
){
if
(
_movH265info
.
hevc
.
numOfArrays
<
1
){
return
;
// waiting for vps/sps/pps
return
;
// waiting for vps/sps/pps
}
}
...
@@ -234,55 +275,49 @@ void Mp4Maker::inputH265_l(void *pData, uint32_t ui32Length, uint32_t ui32TimeSt
...
@@ -234,55 +275,49 @@ void Mp4Maker::inputH265_l(void *pData, uint32_t ui32Length, uint32_t ui32TimeSt
// invalid HVCC
// invalid HVCC
return
;
return
;
}
}
// TODO: waiting for key frame ???
// TODO: waiting for key frame ???
_movH265info
.
videoTrack
=
mov_writer_add_video
(
_movH265info
.
pMov
,
MOV_OBJECT_HEVC
,
_movH265info
.
width
,
_movH265info
.
height
,
sExtraData
,
extraDataSize
);
_movH265info
.
videoTrack
=
mov_writer_add_video
(
_movH265info
.
pMov
,
MOV_OBJECT_HEVC
,
_movH265info
.
width
,
_movH265info
.
height
,
sExtraData
,
extraDataSize
);
if
(
_movH265info
.
videoTrack
<
0
)
return
;
return
;
}
}
if
(
iType
<=
H265Frame
::
NAL_IDR_W_RADL
)
{
uint8_t
*
ptr
=
(
uint8_t
*
)
pData
;
ptr
[
0
]
=
(
uint8_t
)((
ui32Length
-
4
>>
24
)
&
0xFF
);
ptr
[
1
]
=
(
uint8_t
)((
ui32Length
-
4
>>
16
)
&
0xFF
);
ptr
[
2
]
=
(
uint8_t
)((
ui32Length
-
4
>>
8
)
&
0xFF
);
ptr
[
3
]
=
(
uint8_t
)((
ui32Length
-
4
>>
0
)
&
0xFF
);
uint32_t
ui32Pts
=
ui32TimeStamp
<
_movH265info
.
startPts
?
0
:
ui32TimeStamp
-
_movH265info
.
startPts
;
mov_writer_write
(
_movH265info
.
pMov
,
mov_writer_write
(
_movH265info
.
pMov
,
_movH265info
.
videoTrack
,
_movH265info
.
videoTrack
,
_sBbuffer
,
pData
,
n
,
ui32Length
,
ui32
TimeStamp
,
ui32
Pts
,
ui32
TimeStamp
,
ui32
Pts
,
(
iType
>=
16
&&
iType
<=
23
)
?
MOV_AV_FLAG_KEYFREAME
:
0
);
iType
==
H265Frame
::
NAL_IDR_W_RADL
?
MOV_AV_FLAG_KEYFREAME
:
0
);
// mov_writer_write(_movH265info.pMov, _movH265info.videoTrack, _sBbuffer, n, ui32TimeStamp, ui32TimeStamp, 1 == vcl ? MOV_AV_FLAG_KEYFREAME : 0);
}
}
}
#endif
}
}
void
Mp4Maker
::
inputAAC_l
(
void
*
pData
,
uint32_t
ui32Length
,
uint32_t
ui32
Duration
)
{
void
Mp4Maker
::
inputAAC_l
(
void
*
pData
,
uint32_t
ui32Length
,
uint32_t
ui32
TimeStamp
)
{
GET_CONFIG
(
uint32_t
,
recordSec
,
Record
::
kFileSecond
);
GET_CONFIG
(
uint32_t
,
recordSec
,
Record
::
kFileSecond
);
#ifdef MP4_H265RECORD
if
(
_h265Record
)
{
if
(
!
_haveVideo
&&
(
_movH265info
.
pMov
==
NULL
||
_ticker
.
elapsedTime
()
>
recordSec
*
1000
))
{
if
(
!
_haveVideo
&&
(
_movH265info
.
pMov
==
NULL
||
_ticker
.
elapsedTime
()
>
recordSec
*
1000
))
{
_startPts
=
ui32TimeStamp
;
createFile
();
createFile
();
}
}
if
(
-
1
!=
_movH265info
.
audioTrack
&&
_movH265info
.
pMov
!=
NULL
){
if
(
-
1
!=
_movH265info
.
audioTrack
&&
_movH265info
.
pMov
!=
NULL
){
mov_writer_write
(
_movH265info
.
pMov
,
_movH265info
.
audioTrack
,
(
uint8_t
*
)
pData
,
ui32Length
,
ui32Duration
,
ui32Duration
,
0
);
}
uint32_t
ui32Pts
=
ui32TimeStamp
<
_movH265info
.
startPts
?
0
:
ui32TimeStamp
-
_movH265info
.
startPts
;
}
else
mov_writer_write
(
_movH265info
.
pMov
,
_movH265info
.
audioTrack
,
(
uint8_t
*
)
pData
,
ui32Length
,
ui32Pts
,
ui32Pts
,
0
);
#endif
{
if
(
!
_haveVideo
&&
(
_hMp4
==
MP4_INVALID_FILE_HANDLE
||
_ticker
.
elapsedTime
()
>
recordSec
*
1000
))
{
//在I帧率处新建MP4文件
//如果文件未创建或者文件超过10分钟则创建新文件
createFile
();
}
if
(
_hAudio
!=
MP4_INVALID_TRACK_ID
)
{
auto
duration
=
ui32Duration
*
_audioSampleRate
/
1000.0
;
MP4WriteSample
(
_hMp4
,
_hAudio
,
(
uint8_t
*
)
pData
,
ui32Length
,
duration
,
0
,
false
);
}
}
}
}
}
void
Mp4Maker
::
createFile
()
{
void
Mp4Maker
::
createFile
()
{
closeFile
();
closeFile
();
auto
strDate
=
timeStr
(
"%Y-%m-%d"
);
auto
strDate
=
timeStr
(
"%Y-%m-%d"
);
auto
strTime
=
timeStr
(
"%H-%M-%S"
);
auto
strTime
=
timeStr
(
"%H-%M-%S"
);
auto
strFileTmp
=
_strPath
+
strDate
+
"/."
+
strTime
+
".mp4"
;
auto
strFileTmp
=
_strPath
+
strDate
+
"/."
+
strTime
+
".mp4"
;
...
@@ -309,119 +344,65 @@ void Mp4Maker::createFile() {
...
@@ -309,119 +344,65 @@ void Mp4Maker::createFile() {
File
::
createfile_path
(
strFileTmp
.
data
(),
0
);
File
::
createfile_path
(
strFileTmp
.
data
(),
0
);
#endif
#endif
#ifdef MP4_H265RECORD
if
(
_h265Record
){
memset
(
&
_movH265info
,
0
,
sizeof
(
_movH265info
));
memset
(
&
_movH265info
,
0
,
sizeof
(
_movH265info
));
_movH265info
.
videoTrack
=
-
1
;
_movH265info
.
videoTrack
=
-
1
;
_movH265info
.
audioTrack
=
-
1
;
_movH265info
.
audioTrack
=
-
1
;
_movH265info
.
width
=
0
;
_movH265info
.
width
=
0
;
_movH265info
.
height
=
0
;
_movH265info
.
height
=
0
;
_movH265info
.
ptr
=
NULL
;
_movH265info
.
pFile
=
fopen
(
strFileTmp
.
data
(),
"wb+"
);
_movH265info
.
pFile
=
fopen
(
strFileTmp
.
data
(),
"wb+"
);
_movH265info
.
pMov
=
mov_writer_create
(
mov_file_buffer
(),
_movH265info
.
pFile
,
0
/*MOV_FLAG_FASTSTART*/
);
_movH265info
.
startPts
=
_startPts
;
}
else
_movH265info
.
pMov
=
mov_writer_create
(
movfileBuffer
(),
_movH265info
.
pFile
,
0
/*MOV_FLAG_FASTSTART*/
);
#endif
{
_hMp4
=
MP4Create
(
strFileTmp
.
data
(),
MP4_CREATE_64BIT_DATA
);
if
(
_hMp4
==
MP4_INVALID_FILE_HANDLE
)
{
WarnL
<<
"创建MP4文件失败:"
<<
strFileTmp
;
return
;
}
}
//MP4SetTimeScale(_hMp4, 90000);
_strFileTmp
=
strFileTmp
;
_strFileTmp
=
strFileTmp
;
_strFile
=
strFile
;
_strFile
=
strFile
;
_ticker
.
resetTime
();
_ticker
.
resetTime
();
if
(
_h265Record
){
if
(
_h265Record
){
auto
videoTrack
=
dynamic_pointer_cast
<
H265Track
>
(
getTrack
(
TrackVideo
));
auto
videoTrack
=
dynamic_pointer_cast
<
H265Track
>
(
getTrack
(
TrackVideo
));
#ifdef MP4_H265RECORD
if
(
videoTrack
){
if
(
videoTrack
){
_movH265info
.
width
=
videoTrack
->
getVideoWidth
();
_movH265info
.
width
=
videoTrack
->
getVideoWidth
();
_movH265info
.
height
=
videoTrack
->
getVideoHeight
();
_movH265info
.
height
=
videoTrack
->
getVideoHeight
();
}
}
#endif
}
else
{
}
else
{
auto
videoTrack
=
dynamic_pointer_cast
<
H264Track
>
(
getTrack
(
TrackVideo
));
auto
videoTrack
=
dynamic_pointer_cast
<
H264Track
>
(
getTrack
(
TrackVideo
));
if
(
videoTrack
){
if
(
videoTrack
){
auto
&
sps
=
videoTrack
->
getSps
();
// auto &sps = videoTrack->getSps();
auto
&
pps
=
videoTrack
->
getPps
();
// auto &pps = videoTrack->getPps();
_movH265info
.
width
=
videoTrack
->
getVideoWidth
();
_movH265info
.
height
=
videoTrack
->
getVideoHeight
();
_hVideo
=
MP4AddH264VideoTrack
(
_hMp4
,
90000
,
MP4_INVALID_DURATION
,
videoTrack
->
getVideoWidth
(),
videoTrack
->
getVideoHeight
(),
sps
[
1
],
sps
[
2
],
sps
[
3
],
3
);
if
(
_hVideo
!=
MP4_INVALID_TRACK_ID
){
MP4AddH264SequenceParameterSet
(
_hMp4
,
_hVideo
,
(
uint8_t
*
)
sps
.
data
(),
sps
.
size
());
MP4AddH264PictureParameterSet
(
_hMp4
,
_hVideo
,
(
uint8_t
*
)
pps
.
data
(),
pps
.
size
());
}
else
{
WarnL
<<
"添加视频通道失败:"
<<
strFileTmp
;
}
}
}
}
}
if
(
_movH265info
.
width
<=
0
||
_movH265info
.
height
<=
0
)
WarnL
<<
"分辨率获取失败,MP4录制异常"
;
auto
audioTrack
=
dynamic_pointer_cast
<
AACTrack
>
(
getTrack
(
TrackAudio
));
auto
audioTrack
=
dynamic_pointer_cast
<
AACTrack
>
(
getTrack
(
TrackAudio
));
if
(
audioTrack
){
if
(
audioTrack
){
_audioSampleRate
=
audioTrack
->
getAudioSampleRate
();
_audioSampleRate
=
audioTrack
->
getAudioSampleRate
();
_audioChannel
=
audioTrack
->
getAudioChannel
();
_audioChannel
=
audioTrack
->
getAudioChannel
();
#ifdef MP4_H265RECORD
uint8_t
extra_data
[
64
*
1024
];
uint8_t
extra_data
[
64
*
1024
];
if
(
_h265Record
){
_movH265info
.
audioTrack
=
mov_writer_add_audio
(
_movH265info
.
pMov
,
MOV_OBJECT_AAC
,
_audioChannel
,
16
,
_audioSampleRate
,
audioTrack
->
getAacCfg
().
data
(),
2
);
_movH265info
.
audioTrack
=
mov_writer_add_audio
(
_movH265info
.
pMov
,
MOV_OBJECT_AAC
,
_audioChannel
,
16
,
_audioSampleRate
,
audioTrack
->
getAacCfg
().
data
(),
2
);
if
(
-
1
==
_movH265info
.
audioTrack
)
if
(
-
1
==
_movH265info
.
audioTrack
)
WarnL
<<
"添加音频通道失败:"
<<
strFileTmp
;
WarnL
<<
"添加音频通道失败:"
<<
strFileTmp
;
}
else
#endif
{
_hAudio
=
MP4AddAudioTrack
(
_hMp4
,
_audioSampleRate
,
MP4_INVALID_DURATION
,
MP4_MPEG4_AUDIO_TYPE
);
if
(
_hAudio
!=
MP4_INVALID_TRACK_ID
)
{
auto
&
cfg
=
audioTrack
->
getAacCfg
();
MP4SetTrackESConfiguration
(
_hMp4
,
_hAudio
,(
uint8_t
*
)
cfg
.
data
(),
cfg
.
size
());
}
else
{
WarnL
<<
"添加音频通道失败:"
<<
strFileTmp
;
}
}
}
}
}
}
void
Mp4Maker
::
asyncClose
()
{
void
Mp4Maker
::
asyncClose
()
{
// auto hMp4 = (_h265Record==0)?_hMp4:_movH265info.pMov;
auto
strFileTmp
=
_strFileTmp
;
auto
strFileTmp
=
_strFileTmp
;
auto
strFile
=
_strFile
;
auto
strFile
=
_strFile
;
auto
info
=
_info
;
auto
info
=
_info
;
int
h265Record
=
_h265Record
;
FILE
*
pFile
=
_movH265info
.
pFile
;
#ifdef MP4_H265RECORD
mov_writer_t
*
hMp4
=
_movH265info
.
pMov
;
FILE
*
pFile
=
(
_h265Record
)
?
_movH265info
.
pFile
:
NULL
;
WorkThreadPool
::
Instance
().
getExecutor
()
->
async
([
hMp4
,
strFileTmp
,
strFile
,
info
,
pFile
]()
{
void
*
hMp4
=
(
_h265Record
)
?
(
void
*
)
_movH265info
.
pMov
:
(
void
*
)
_hMp4
;
#else
auto
hMp4
=
_hMp4
;
FILE
*
pFile
=
NULL
;
#endif
WorkThreadPool
::
Instance
().
getExecutor
()
->
async
([
hMp4
,
strFileTmp
,
strFile
,
info
,
pFile
,
h265Record
]()
{
//获取文件录制时间,放在MP4Close之前是为了忽略MP4Close执行时间
//获取文件录制时间,放在MP4Close之前是为了忽略MP4Close执行时间
const_cast
<
Mp4Info
&>
(
info
).
ui64TimeLen
=
::
time
(
NULL
)
-
info
.
ui64StartedTime
;
const_cast
<
Mp4Info
&>
(
info
).
ui64TimeLen
=
::
time
(
NULL
)
-
info
.
ui64StartedTime
;
//MP4Close非常耗时,所以要放在后台线程执行
//MP4Close非常耗时,所以要放在后台线程执行
if
(
hMp4
!=
NULL
){
#ifdef MP4_H265RECORD
mov_writer_destroy
(
hMp4
);
if
(
h265Record
){
mov_writer_destroy
((
mov_writer_t
*
)
hMp4
);
fclose
(
pFile
);
fclose
(
pFile
);
}
else
DebugL
<<
"fclose end"
;
#endif
{
MP4Close
(
hMp4
,
MP4_CLOSE_DO_NOT_COMPUTE_BITRATE
);
}
}
//临时文件名改成正式文件名,防止mp4未完成时被访问
//临时文件名改成正式文件名,防止mp4未完成时被访问
rename
(
strFileTmp
.
data
(),
strFile
.
data
());
rename
(
strFileTmp
.
data
(),
strFile
.
data
());
//获取文件大小
//获取文件大小
...
@@ -434,35 +415,30 @@ void Mp4Maker::asyncClose() {
...
@@ -434,35 +415,30 @@ void Mp4Maker::asyncClose() {
}
}
void
Mp4Maker
::
closeFile
()
{
void
Mp4Maker
::
closeFile
()
{
#ifdef MP4_H265RECORD
if
(
_h265Record
){
if
(
_movH265info
.
pMov
!=
NULL
)
{
if
(
_movH265info
.
pMov
!=
NULL
)
{
asyncClose
();
asyncClose
();
}
memset
(
&
_movH265info
,
0
,
sizeof
(
_movH265info
));
}
else
_movH265info
.
pMov
=
NULL
;
#endif
_movH265info
.
videoTrack
=
-
1
;
{
_movH265info
.
audioTrack
=
-
1
;
if
(
_hMp4
!=
MP4_INVALID_FILE_HANDLE
)
{
asyncClose
();
_hMp4
=
MP4_INVALID_FILE_HANDLE
;
_hVideo
=
MP4_INVALID_TRACK_ID
;
_hAudio
=
MP4_INVALID_TRACK_ID
;
}
}
}
}
}
void
Mp4Maker
::
onTrackFrame
(
const
Frame
::
Ptr
&
frame
)
{
void
Mp4Maker
::
onTrackFrame
(
const
Frame
::
Ptr
&
frame
)
{
switch
(
frame
->
getCodecId
()){
switch
(
frame
->
getCodecId
()){
case
CodecH264
:{
case
CodecH264
:{
inputH264
(
frame
->
data
()
+
frame
->
prefixSize
(),
frame
->
size
()
-
frame
->
prefixSize
(),
frame
->
stamp
());
//需要带00 00 00 01,方便在mov_writer_write的时候字节修改这4Byte为长度信息
inputH264
(
frame
->
data
()
,
frame
->
size
(),
frame
->
pts
());
}
}
break
;
break
;
case
CodecAAC
:{
case
CodecAAC
:{
inputAAC
(
frame
->
data
()
+
frame
->
prefixSize
(),
frame
->
size
()
-
frame
->
prefixSize
(),
frame
->
stamp
());
//不需要ADTS头
inputAAC
(
frame
->
data
()
+
frame
->
prefixSize
(),
frame
->
size
()
-
frame
->
prefixSize
(),
frame
->
pts
());
}
}
break
;
break
;
case
CodecH265
:{
case
CodecH265
:{
inputH265
(
frame
->
data
()
,
frame
->
size
(),
frame
->
stamp
());
//需要带00 00 00 01,方便在mov_writer_write的时候字节修改这4Byte为长度信息
inputH265
(
frame
->
data
()
,
frame
->
size
(),
frame
->
pts
());
}
}
break
;
break
;
default
:
default
:
...
@@ -477,4 +453,4 @@ void Mp4Maker::onAllTrackReady() {
...
@@ -477,4 +453,4 @@ void Mp4Maker::onAllTrackReady() {
}
/* namespace mediakit */
}
/* namespace mediakit */
#endif //ENABLE_MP4
V2
#endif //ENABLE_MP4
RECORD
\ No newline at end of file
src/MediaFile/Mp4Maker.h
查看文件 @
124cce34
...
@@ -27,11 +27,10 @@
...
@@ -27,11 +27,10 @@
#ifndef MP4MAKER_H_
#ifndef MP4MAKER_H_
#define MP4MAKER_H_
#define MP4MAKER_H_
#ifdef ENABLE_MP4
V2
#ifdef ENABLE_MP4
RECORD
#include <mutex>
#include <mutex>
#include <memory>
#include <memory>
#include <mp4v2/mp4v2.h>
#include "Player/PlayerBase.h"
#include "Player/PlayerBase.h"
#include "Util/util.h"
#include "Util/util.h"
#include "Util/logger.h"
#include "Util/logger.h"
...
@@ -41,10 +40,10 @@
...
@@ -41,10 +40,10 @@
#include "Extension/Track.h"
#include "Extension/Track.h"
#ifdef MP4_H265RECORD
#include "mov-writer.h"
#include "mov-writer.h"
#include "mpeg4-hevc.h"
#include "mpeg4-hevc.h"
#endif
#include "mpeg4-avc.h"
using
namespace
toolkit
;
using
namespace
toolkit
;
...
@@ -66,17 +65,15 @@ public:
...
@@ -66,17 +65,15 @@ public:
class
MovH265Info
{
class
MovH265Info
{
public
:
public
:
#ifdef MP4_H265RECORD
mov_writer_t
*
pMov
;
mov_writer_t
*
pMov
;
struct
mpeg4_hevc_t
hevc
;
struct
mpeg4_hevc_t
hevc
;
struct
mpeg4_avc_t
avc
;
int
videoTrack
;
int
videoTrack
;
int
audioTrack
;
int
audioTrack
;
int
width
;
int
width
;
int
height
;
int
height
;
const
uint8_t
*
ptr
;
uint32_t
startPts
;
FILE
*
pFile
;
FILE
*
pFile
;
#endif
};
};
class
Mp4Maker
:
public
MediaSink
{
class
Mp4Maker
:
public
MediaSink
{
...
@@ -109,19 +106,16 @@ private:
...
@@ -109,19 +106,16 @@ private:
//时间戳:参考频率1000
//时间戳:参考频率1000
void
inputAAC
(
void
*
pData
,
uint32_t
ui32Length
,
uint32_t
ui32TimeStamp
);
void
inputAAC
(
void
*
pData
,
uint32_t
ui32Length
,
uint32_t
ui32TimeStamp
);
void
inputH264_l
(
void
*
pData
,
uint32_t
ui32Length
,
uint32_t
ui
64Duration
);
void
inputH264_l
(
void
*
pData
,
uint32_t
ui32Length
,
uint32_t
ui
32TimeStamp
);
void
inputH265_l
(
void
*
pData
,
uint32_t
ui32Length
,
uint32_t
ui32TimeStamp
);
void
inputH265_l
(
void
*
pData
,
uint32_t
ui32Length
,
uint32_t
ui32TimeStamp
);
void
inputAAC_l
(
void
*
pData
,
uint32_t
ui32Length
,
uint32_t
ui
64Duration
);
void
inputAAC_l
(
void
*
pData
,
uint32_t
ui32Length
,
uint32_t
ui
32TimeStamp
);
private
:
private
:
MovH265Info
_movH265info
;
MovH265Info
_movH265info
;
int
_h265Record
=
0
;
int
_h265Record
=
0
;
uint32_t
_startPts
;
uint8_t
_sBbuffer
[
2
*
1024
*
1024
];
uint8_t
_sBbuffer
[
2
*
1024
*
1024
];
MP4FileHandle
_hMp4
=
MP4_INVALID_FILE_HANDLE
;
MP4TrackId
_hVideo
=
MP4_INVALID_TRACK_ID
;
MP4TrackId
_hAudio
=
MP4_INVALID_TRACK_ID
;
string
_strPath
;
string
_strPath
;
string
_strFile
;
string
_strFile
;
string
_strFileTmp
;
string
_strFileTmp
;
...
@@ -141,6 +135,6 @@ private:
...
@@ -141,6 +135,6 @@ private:
}
/* namespace mediakit */
}
/* namespace mediakit */
#endif ///ENABLE_MP4
V2
#endif ///ENABLE_MP4
RECORD
#endif
/* MP4MAKER_H_ */
#endif
/* MP4MAKER_H_ */
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论