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
383a14a7
Commit
383a14a7
authored
Aug 01, 2019
by
xiongziliang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
重新mp4录制
parent
12e1068a
全部展开
隐藏空白字符变更
内嵌
并排
正在显示
14 个修改的文件
包含
433 行增加
和
86 行删除
+433
-86
3rdpart/media-server
+1
-1
src/Extension/AAC.h
+8
-0
src/Extension/Frame.h
+12
-0
src/Extension/H264.h
+20
-0
src/Extension/H265.h
+29
-8
src/Extension/H265Rtp.cpp
+21
-21
src/Extension/H265Rtp.h
+1
-0
src/MediaFile/MP4Muxer.cpp
+230
-0
src/MediaFile/MP4Muxer.h
+98
-0
src/MediaFile/MediaRecorder.cpp
+2
-2
src/MediaFile/MediaRecorder.h
+2
-2
src/MediaFile/Mp4Maker.cpp
+0
-0
src/MediaFile/Mp4Maker.h
+5
-49
src/MediaFile/TsMuxer.h
+4
-3
没有找到文件。
media-server
@
6df71e01
Subproject commit
a32fe104c0290bc01a7ee73d50b568e8d9ded931
Subproject commit
6df71e01c174cdfe69e597cc4acb766a20b28620
src/Extension/AAC.h
查看文件 @
383a14a7
...
...
@@ -79,6 +79,10 @@ public:
bool
keyFrame
()
const
override
{
return
false
;
}
bool
configFrame
()
const
override
{
return
false
;
}
public
:
unsigned
int
syncword
=
0
;
//12 bslbf 同步字The bit string ‘1111 1111 1111’,说明一个ADTS帧的开始
unsigned
int
id
;
//1 bslbf MPEG 标示符, 设置为1
...
...
@@ -127,6 +131,10 @@ public:
bool
keyFrame
()
const
override
{
return
false
;
}
bool
configFrame
()
const
override
{
return
false
;
}
}
;
...
...
src/Extension/Frame.h
查看文件 @
383a14a7
...
...
@@ -118,6 +118,12 @@ public:
virtual
bool
keyFrame
()
const
=
0
;
/**
* 是否为配置帧,譬如sps pps vps
* @return
*/
virtual
bool
configFrame
()
const
=
0
;
/**
* 是否可以缓存
*/
virtual
bool
cacheAble
()
const
{
return
true
;
}
...
...
@@ -371,6 +377,7 @@ public:
_trackType
=
frame
->
getTrackType
();
_codec
=
frame
->
getCodecId
();
_key
=
frame
->
keyFrame
();
_config
=
frame
->
configFrame
();
}
virtual
~
FrameCacheAble
()
=
default
;
...
...
@@ -394,12 +401,17 @@ public:
bool
keyFrame
()
const
override
{
return
_key
;
}
bool
configFrame
()
const
override
{
return
_config
;
}
private
:
Frame
::
Ptr
_frame
;
BufferRaw
::
Ptr
_buffer
;
TrackType
_trackType
;
CodecId
_codec
;
bool
_key
;
bool
_config
;
};
...
...
src/Extension/H264.h
查看文件 @
383a14a7
...
...
@@ -82,6 +82,16 @@ public:
bool
keyFrame
()
const
override
{
return
H264_TYPE
(
buffer
[
iPrefixSize
])
==
H264Frame
::
NAL_IDR
;
}
bool
configFrame
()
const
override
{
switch
(
H264_TYPE
(
buffer
[
iPrefixSize
])
){
case
H264Frame
:
:
NAL_SPS
:
case
H264Frame
:
:
NAL_PPS
:
return
true
;
default
:
return
false
;
}
}
public
:
uint32_t
timeStamp
;
uint32_t
ptsStamp
=
0
;
...
...
@@ -118,6 +128,16 @@ public:
bool
keyFrame
()
const
override
{
return
H264_TYPE
(
_ptr
[
_prefixSize
])
==
H264Frame
::
NAL_IDR
;
}
bool
configFrame
()
const
override
{
switch
(
H264_TYPE
(
_ptr
[
_prefixSize
])){
case
H264Frame
:
:
NAL_SPS
:
case
H264Frame
:
:
NAL_PPS
:
return
true
;
default
:
return
false
;
}
}
};
/**
...
...
src/Extension/H265.h
查看文件 @
383a14a7
...
...
@@ -86,6 +86,10 @@ public:
return
timeStamp
;
}
uint32_t
pts
()
const
override
{
return
ptsStamp
?
ptsStamp
:
timeStamp
;
}
uint32_t
prefixSize
()
const
override
{
return
iPrefixSize
;
}
...
...
@@ -99,7 +103,18 @@ public:
}
bool
keyFrame
()
const
override
{
return
isKeyFrame
(
type
);
return
isKeyFrame
(
H265_TYPE
(
buffer
[
iPrefixSize
]));
}
bool
configFrame
()
const
override
{
switch
(
H265_TYPE
(
buffer
[
iPrefixSize
])){
case
H265Frame
:
:
NAL_VPS
:
case
H265Frame
:
:
NAL_SPS
:
case
H265Frame
:
:
NAL_PPS
:
return
true
;
default
:
return
false
;
}
}
static
bool
isKeyFrame
(
int
type
)
{
...
...
@@ -117,9 +132,8 @@ public:
}
public
:
uint16_t
sequence
;
uint32_t
timeStamp
;
u
nsigned
char
type
;
u
int32_t
ptsStamp
=
0
;
string
buffer
;
uint32_t
iPrefixSize
=
4
;
};
...
...
@@ -146,8 +160,18 @@ public:
}
bool
keyFrame
()
const
override
{
int
type
=
H265_TYPE
(((
uint8_t
*
)
_ptr
)[
_prefixSize
]);
return
H265Frame
::
isKeyFrame
(
type
);
return
H265Frame
::
isKeyFrame
(
H265_TYPE
(((
uint8_t
*
)
_ptr
)[
_prefixSize
]));
}
bool
configFrame
()
const
override
{
switch
(
H265_TYPE
(((
uint8_t
*
)
_ptr
)[
_prefixSize
])){
case
H265Frame
:
:
NAL_VPS
:
case
H265Frame
:
:
NAL_SPS
:
case
H265Frame
:
:
NAL_PPS
:
return
true
;
default
:
return
false
;
}
}
};
...
...
@@ -328,7 +352,6 @@ private:
}
if
(
!
_vps
.
empty
()){
auto
vpsFrame
=
std
::
make_shared
<
H265Frame
>
();
vpsFrame
->
type
=
H265Frame
::
NAL_VPS
;
vpsFrame
->
iPrefixSize
=
4
;
vpsFrame
->
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
vpsFrame
->
buffer
.
append
(
_vps
);
...
...
@@ -337,7 +360,6 @@ private:
}
if
(
!
_sps
.
empty
())
{
auto
spsFrame
=
std
::
make_shared
<
H265Frame
>
();
spsFrame
->
type
=
H265Frame
::
NAL_SPS
;
spsFrame
->
iPrefixSize
=
4
;
spsFrame
->
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
spsFrame
->
buffer
.
append
(
_sps
);
...
...
@@ -347,7 +369,6 @@ private:
if
(
!
_pps
.
empty
())
{
auto
ppsFrame
=
std
::
make_shared
<
H265Frame
>
();
ppsFrame
->
type
=
H265Frame
::
NAL_PPS
;
ppsFrame
->
iPrefixSize
=
4
;
ppsFrame
->
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
ppsFrame
->
buffer
.
append
(
_pps
);
...
...
src/Extension/H265Rtp.cpp
查看文件 @
383a14a7
...
...
@@ -99,56 +99,56 @@ bool H265RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
// fragmentation unit (FU)
FU
fu
;
MakeFU
(
frame
[
2
],
fu
);
if
(
fu
.
S
==
1
)
{
//
FU-A start
if
(
fu
.
S
)
{
//
该帧的第一个rtp包
_h265frame
->
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
_h265frame
->
buffer
.
push_back
(
fu
.
type
<<
1
);
_h265frame
->
buffer
.
push_back
(
0x01
);
_h265frame
->
buffer
.
append
((
char
*
)
frame
+
3
,
length
-
3
);
_h265frame
->
type
=
fu
.
type
;
_h265frame
->
timeStamp
=
rtppack
->
timeStamp
;
_h265frame
->
sequence
=
rtppack
->
sequence
;
//该函数return时,保存下当前sequence,以便下次对比seq是否连续
_lastSeq
=
rtppack
->
sequence
;
return
(
_h265frame
->
keyFrame
());
//i frame
}
if
(
rtppack
->
sequence
!=
(
uint16_t
)
(
_h265frame
->
sequence
+
1
))
{
if
(
rtppack
->
sequence
!=
_lastSeq
+
1
&&
rtppack
->
sequence
!=
0
)
{
//中间的或末尾的rtp包,其seq必须连续(如果回环了则判定为连续),否则说明rtp丢包,那么该帧不完整,必须得丢弃
_h265frame
->
buffer
.
clear
();
WarnL
<<
"
丢包,帧废弃:"
<<
rtppack
->
sequence
<<
","
<<
_h265frame
->
sequence
;
WarnL
<<
"
rtp sequence不连续: "
<<
rtppack
->
sequence
<<
" != "
<<
_lastSeq
<<
" + 1,该帧被废弃"
;
return
false
;
}
_h265frame
->
sequence
=
rtppack
->
sequence
;
if
(
fu
.
E
==
1
)
{
//
FU-A end
if
(
!
fu
.
E
)
{
//
该帧的中间rtp包
_h265frame
->
buffer
.
append
((
char
*
)
frame
+
3
,
length
-
3
);
_h265frame
->
timeStamp
=
rtppack
->
timeStamp
;
auto
isIDR
=
_h265frame
->
keyFrame
();
onGetH265
(
_h265frame
);
return
isIDR
;
//该函数return时,保存下当前sequence,以便下次对比seq是否连续
_lastSeq
=
rtppack
->
sequence
;
return
false
;
}
//FU-A mid
//该帧最后一个rtp包
_h265frame
->
buffer
.
append
((
char
*
)
frame
+
3
,
length
-
3
);
return
false
;
_h265frame
->
timeStamp
=
rtppack
->
timeStamp
;
auto
key
=
_h265frame
->
keyFrame
();
onGetH265
(
_h265frame
);
return
key
;
}
default
:
// 4.4.1. Single NAL Unit Packets (p24)
//a full frame
_h265frame
->
buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
_h265frame
->
buffer
.
append
((
char
*
)
frame
,
length
);
_h265frame
->
type
=
nal
;
_h265frame
->
timeStamp
=
rtppack
->
timeStamp
;
_h265frame
->
sequence
=
rtppack
->
sequence
;
auto
isIDR
=
_h265frame
->
keyFrame
();
auto
key
=
_h265frame
->
keyFrame
();
onGetH265
(
_h265frame
);
return
(
isIDR
);
//i frame
return
key
;
}
}
void
H265RtpDecoder
::
onGetH265
(
const
H265Frame
::
Ptr
&
frame
)
{
//写入环形缓存
auto
lastSeq
=
_h265frame
->
sequence
;
RtpCodec
::
inputFrame
(
frame
);
_h265frame
=
obtainFrame
();
_h265frame
->
sequence
=
lastSeq
;
}
...
...
src/Extension/H265Rtp.h
查看文件 @
383a14a7
...
...
@@ -65,6 +65,7 @@ private:
H265Frame
::
Ptr
obtainFrame
();
private
:
H265Frame
::
Ptr
_h265frame
;
int
_lastSeq
=
0
;
};
/**
...
...
src/MediaFile/MP4Muxer.cpp
0 → 100644
查看文件 @
383a14a7
/*
* MIT License
*
* Copyright (c) 2016-2019 xiongziliang <771730766@qq.com>
*
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifdef ENABLE_MP4RECORD
#include "MP4Muxer.h"
#include "Util/File.h"
namespace
mediakit
{
#if defined(_WIN32) || defined(_WIN64)
#define fseek64 _fseeki64
#define ftell64 _ftelli64
#else
#define fseek64 fseek
#define ftell64 ftell
#endif
MP4MuxerBase
::
MP4MuxerBase
(
int
flags
)
{
static
struct
mov_buffer_t
s_io
=
{
[](
void
*
ctx
,
void
*
data
,
uint64_t
bytes
)
{
MP4MuxerBase
*
thiz
=
(
MP4MuxerBase
*
)
ctx
;
return
thiz
->
onRead
(
data
,
bytes
);
},
[](
void
*
ctx
,
const
void
*
data
,
uint64_t
bytes
){
MP4MuxerBase
*
thiz
=
(
MP4MuxerBase
*
)
ctx
;
return
thiz
->
onWrite
(
data
,
bytes
);
},
[](
void
*
ctx
,
uint64_t
offset
)
{
MP4MuxerBase
*
thiz
=
(
MP4MuxerBase
*
)
ctx
;
return
thiz
->
onSeek
(
offset
);
},
[](
void
*
ctx
){
MP4MuxerBase
*
thiz
=
(
MP4MuxerBase
*
)
ctx
;
return
thiz
->
onTell
();
}
};
_mov_writter
.
reset
(
mov_writer_create
(
&
s_io
,
this
,
flags
),[](
mov_writer_t
*
ptr
){
if
(
ptr
){
mov_writer_destroy
(
ptr
);
}
});
}
///////////////////////////////////
MP4Muxer
::
MP4Muxer
(
int
flags
)
:
MP4MuxerBase
(
flags
)
{
}
void
MP4Muxer
::
onTrackFrame
(
const
Frame
::
Ptr
&
frame
)
{
if
(
frame
->
configFrame
()){
//忽略配置帧
return
;
}
auto
it
=
_codec_to_trackid
.
find
(
frame
->
getCodecId
());
if
(
it
==
_codec_to_trackid
.
end
()){
return
;
}
mov_writer_write_l
(
_mov_writter
.
get
(),
it
->
second
,
frame
->
data
()
+
frame
->
prefixSize
(),
frame
->
size
()
-
frame
->
prefixSize
(),
frame
->
pts
(),
frame
->
dts
(),
frame
->
keyFrame
()
?
MOV_AV_FLAG_KEYFREAME
:
0
,
0
);
}
void
MP4Muxer
::
onTrackReady
(
const
Track
::
Ptr
&
track
)
{
switch
(
track
->
getCodecId
())
{
case
CodecAAC
:
{
auto
aac_track
=
dynamic_pointer_cast
<
AACTrack
>
(
track
);
if
(
!
aac_track
)
{
WarnL
<<
"不是AAC Track"
;
return
;
}
auto
track_id
=
mov_writer_add_audio
(
_mov_writter
.
get
(),
MOV_OBJECT_AAC
,
aac_track
->
getAudioChannel
(),
aac_track
->
getAudioSampleBit
(),
aac_track
->
getAudioSampleRate
(),
aac_track
->
getAacCfg
().
data
(),
2
);
_codec_to_trackid
[
track
->
getCodecId
()]
=
track_id
;
}
break
;
case
CodecH264
:
{
auto
h264_track
=
dynamic_pointer_cast
<
H264Track
>
(
track
);
if
(
!
h264_track
)
{
WarnL
<<
"不是H264 Track"
;
return
;
}
struct
mpeg4_avc_t
avc
;
string
sps_pps
=
string
(
"
\x00\x00\x00\x01
"
,
4
)
+
h264_track
->
getSps
()
+
string
(
"
\x00\x00\x00\x01
"
,
4
)
+
h264_track
->
getPps
();
h264_annexbtomp4
(
&
avc
,
sps_pps
.
data
(),
sps_pps
.
size
(),
NULL
,
0
,
NULL
);
uint8_t
extra_data
[
1024
];
int
extra_data_size
=
mpeg4_avc_decoder_configuration_record_save
(
&
avc
,
extra_data
,
sizeof
(
extra_data
));
if
(
extra_data_size
==
-
1
)
{
WarnL
<<
"生成H264 extra_data 失败"
;
return
;
}
auto
track_id
=
mov_writer_add_video
(
_mov_writter
.
get
(),
MOV_OBJECT_H264
,
h264_track
->
getVideoWidth
(),
h264_track
->
getVideoHeight
(),
extra_data
,
extra_data_size
);
_codec_to_trackid
[
track
->
getCodecId
()]
=
track_id
;
}
break
;
case
CodecH265
:
{
auto
h265_track
=
dynamic_pointer_cast
<
H265Track
>
(
track
);
if
(
!
h265_track
)
{
WarnL
<<
"不是H265 Track"
;
return
;
}
struct
mpeg4_hevc_t
hevc
;
string
vps_sps_pps
=
string
(
"
\x00\x00\x00\x01
"
,
4
)
+
h265_track
->
getVps
()
+
string
(
"
\x00\x00\x00\x01
"
,
4
)
+
h265_track
->
getSps
()
+
string
(
"
\x00\x00\x00\x01
"
,
4
)
+
h265_track
->
getPps
();
h265_annexbtomp4
(
&
hevc
,
vps_sps_pps
.
data
(),
vps_sps_pps
.
size
(),
NULL
,
0
,
NULL
);
uint8_t
extra_data
[
1024
];
int
extra_data_size
=
mpeg4_hevc_decoder_configuration_record_save
(
&
hevc
,
extra_data
,
sizeof
(
extra_data
));
if
(
extra_data_size
==
-
1
)
{
WarnL
<<
"生成H265 extra_data 失败"
;
return
;
}
auto
track_id
=
mov_writer_add_video
(
_mov_writter
.
get
(),
MOV_OBJECT_HEVC
,
h265_track
->
getVideoWidth
(),
h265_track
->
getVideoHeight
(),
extra_data
,
extra_data_size
);
_codec_to_trackid
[
track
->
getCodecId
()]
=
track_id
;
}
break
;
default
:
WarnL
<<
"MP4录制不支持该编码格式:"
<<
track
->
getCodecId
();
break
;
}
}
#define FILE_BUF_SIZE (64 * 1024)
MP4MuxerFile
::
MP4MuxerFile
(
const
char
*
file
)
{
//创建文件
auto
fp
=
File
::
createfile_file
(
file
,
"wb"
);
if
(
!
fp
){
throw
std
::
runtime_error
(
string
(
"打开文件失败:"
)
+
file
);
}
//新建文件io缓存
std
::
shared_ptr
<
char
>
file_buf
(
new
char
[
FILE_BUF_SIZE
],[](
char
*
ptr
){
if
(
ptr
){
delete
[]
ptr
;
}
});
if
(
file_buf
){
//设置文件io缓存
setvbuf
(
fp
,
file_buf
.
get
(),
_IOFBF
,
FILE_BUF_SIZE
);
}
//创建智能指针
_file
.
reset
(
fp
,[
file_buf
](
FILE
*
fp
)
{
fclose
(
fp
);
});
}
int
MP4MuxerFile
::
onRead
(
void
*
data
,
uint64_t
bytes
)
{
return
fread
(
data
,
1
,
bytes
,
_file
.
get
());
}
int
MP4MuxerFile
::
onWrite
(
const
void
*
data
,
uint64_t
bytes
)
{
return
fwrite
(
data
,
1
,
bytes
,
_file
.
get
());
}
#if defined(_WIN32) || defined(_WIN64)
#define fseek64 _fseeki64
#define ftell64 _ftelli64
#else
#define fseek64 fseek
#define ftell64 ftell
#endif
int
MP4MuxerFile
::
onSeek
(
uint64_t
offset
)
{
return
fseek64
(
_file
.
get
(),
offset
,
SEEK_SET
);
}
uint64_t
MP4MuxerFile
::
onTell
()
{
return
ftell64
(
_file
.
get
());
}
}
//namespace mediakit
#endif//#ifdef ENABLE_MP4RECORD
src/MediaFile/MP4Muxer.h
0 → 100644
查看文件 @
383a14a7
/*
* MIT License
*
* Copyright (c) 2016-2019 xiongziliang <771730766@qq.com>
*
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef ZLMEDIAKIT_MP4MUXER_H
#define ZLMEDIAKIT_MP4MUXER_H
#ifdef ENABLE_MP4RECORD
#include "Common/MediaSink.h"
#include "mov-writer.h"
#include "mpeg4-hevc.h"
#include "mpeg4-avc.h"
#include "mpeg4-aac.h"
#include "mov-buffer.h"
#include "mov-format.h"
#include "Extension/AAC.h"
#include "Extension/H264.h"
#include "Extension/H265.h"
namespace
mediakit
{
class
MP4MuxerBase
{
public
:
MP4MuxerBase
(
int
flags
=
MOV_FLAG_FASTSTART
);
virtual
~
MP4MuxerBase
()
=
default
;
protected
:
virtual
int
onRead
(
void
*
data
,
uint64_t
bytes
)
=
0
;
virtual
int
onWrite
(
const
void
*
data
,
uint64_t
bytes
)
=
0
;
virtual
int
onSeek
(
uint64_t
offset
)
=
0
;
virtual
uint64_t
onTell
()
=
0
;
protected
:
std
::
shared_ptr
<
mov_writer_t
>
_mov_writter
;
};
class
MP4Muxer
:
public
MediaSink
,
public
MP4MuxerBase
{
public
:
MP4Muxer
(
int
flags
=
MOV_FLAG_FASTSTART
)
;
~
MP4Muxer
()
override
=
default
;
protected
:
/**
* 某track已经准备好,其ready()状态返回true,
* 此时代表可以获取其例如sps pps等相关信息了
* @param track
*/
void
onTrackReady
(
const
Track
::
Ptr
&
track
)
override
;
/**
* 某Track输出frame,在onAllTrackReady触发后才会调用此方法
* @param frame
*/
void
onTrackFrame
(
const
Frame
::
Ptr
&
frame
)
override
;
private
:
map
<
CodecId
,
int
>
_codec_to_trackid
;
};
class
MP4MuxerFile
:
public
MP4Muxer
{
public
:
typedef
std
::
shared_ptr
<
MP4MuxerFile
>
Ptr
;
MP4MuxerFile
(
const
char
*
file
);
~
MP4MuxerFile
()
=
default
;
protected
:
int
onRead
(
void
*
data
,
uint64_t
bytes
)
override
;
int
onWrite
(
const
void
*
data
,
uint64_t
bytes
)
override
;
int
onSeek
(
uint64_t
offset
)
override
;
uint64_t
onTell
()
override
;
private
:
std
::
shared_ptr
<
FILE
>
_file
;
};
}
//namespace mediakit
#endif//#ifdef ENABLE_MP4RECORD
#endif //ZLMEDIAKIT_MP4MUXER_H
src/MediaFile/MediaRecorder.cpp
查看文件 @
383a14a7
...
...
@@ -106,11 +106,11 @@ void MediaRecorder::addTrack(const Track::Ptr &track) {
}
#endif //defined(ENABLE_HLS)
#if defined(ENABLE_MP4
V2
)
#if defined(ENABLE_MP4
RECORD
)
if
(
_mp4Maker
)
{
_mp4Maker
->
addTrack
(
track
);
}
#endif //defined(ENABLE_MP4
V2
)
#endif //defined(ENABLE_MP4
RECORD
)
}
}
/* namespace mediakit */
src/MediaFile/MediaRecorder.h
查看文件 @
383a14a7
...
...
@@ -64,9 +64,9 @@ private:
std
::
shared_ptr
<
HlsRecorder
>
_hlsMaker
;
#endif //defined(ENABLE_HLS)
#if defined(ENABLE_MP4
V2
)
#if defined(ENABLE_MP4
RECORD
)
std
::
shared_ptr
<
Mp4Maker
>
_mp4Maker
;
#endif //defined(ENABLE_MP4
V2
)
#endif //defined(ENABLE_MP4
RECORD
)
};
}
/* namespace mediakit */
...
...
src/MediaFile/Mp4Maker.cpp
查看文件 @
383a14a7
差异被折叠。
点击展开。
src/MediaFile/Mp4Maker.h
查看文件 @
383a14a7
/*
/*
* MIT License
*
* Copyright (c) 2016-2019 xiongziliang <771730766@qq.com>
...
...
@@ -37,14 +37,7 @@
#include "Util/TimeTicker.h"
#include "Util/TimeTicker.h"
#include "Common/MediaSink.h"
#include "Extension/Track.h"
#include "mov-writer.h"
#include "mpeg4-hevc.h"
#include "mpeg4-avc.h"
#include "MP4Muxer.h"
using
namespace
toolkit
;
namespace
mediakit
{
...
...
@@ -62,20 +55,6 @@ public:
string
strStreamId
;
//流ID
string
strVhost
;
//vhost
};
class
MovH265Info
{
public
:
mov_writer_t
*
pMov
;
struct
mpeg4_hevc_t
hevc
;
struct
mpeg4_avc_t
avc
;
int
videoTrack
;
int
audioTrack
;
int
width
;
int
height
;
uint32_t
startPts
;
FILE
*
pFile
;
};
class
Mp4Maker
:
public
MediaSink
{
public
:
typedef
std
::
shared_ptr
<
Mp4Maker
>
Ptr
;
...
...
@@ -99,38 +78,15 @@ private:
void
createFile
();
void
closeFile
();
void
asyncClose
();
//时间戳:参考频率1000
void
inputH264
(
void
*
pData
,
uint32_t
ui32Length
,
uint32_t
ui32TimeStamp
);
void
inputH265
(
void
*
pData
,
uint32_t
ui32Length
,
uint32_t
ui32TimeStamp
);
//时间戳:参考频率1000
void
inputAAC
(
void
*
pData
,
uint32_t
ui32Length
,
uint32_t
ui32TimeStamp
);
void
inputH264_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
ui32TimeStamp
);
private
:
MovH265Info
_movH265info
;
int
_h265Record
=
0
;
uint32_t
_startPts
;
uint8_t
_sBbuffer
[
2
*
1024
*
1024
];
string
_strPath
;
string
_strFile
;
string
_strFileTmp
;
Ticker
_ticker
;
string
_strLastVideo
;
string
_strLastAudio
;
uint32_t
_ui32LastVideoTime
=
0
;
uint32_t
_ui32LastAudioTime
=
0
;
Ticker
_createFileTicker
;
Mp4Info
_info
;
bool
_haveVideo
=
false
;
int
_audioSampleRate
;
int
_audioChannel
;
MP4MuxerFile
::
Ptr
_muxer
;
list
<
Track
::
Ptr
>
_tracks
;
};
}
/* namespace mediakit */
...
...
src/MediaFile/TsMuxer.h
查看文件 @
383a14a7
...
...
@@ -31,16 +31,17 @@
#include "Extension/Frame.h"
#include "Extension/Track.h"
#include "Util/File.h"
#include "Common/MediaSink.h"
using
namespace
toolkit
;
namespace
mediakit
{
class
TsMuxer
{
class
TsMuxer
:
public
MediaSink
{
public
:
TsMuxer
();
virtual
~
TsMuxer
();
void
addTrack
(
const
Track
::
Ptr
&
track
);
void
inputFrame
(
const
Frame
::
Ptr
&
frame
);
void
addTrack
(
const
Track
::
Ptr
&
track
)
override
;
void
inputFrame
(
const
Frame
::
Ptr
&
frame
)
override
;
protected
:
virtual
void
onTs
(
const
void
*
packet
,
int
bytes
,
uint32_t
timestamp
,
int
flags
)
=
0
;
void
resetTracks
();
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论