Package io.antmedia.muxer
Class Muxer
java.lang.Object
io.antmedia.muxer.Muxer
- Direct Known Subclasses:
HLSMuxer
,RecordMuxer
,RtmpMuxer
PLEASE READ HERE BEFORE YOU IMPLEMENT A MUXER THAT INHERITS THIS CLASS
One muxer can be used by multiple encoder so some functions(init,
writeTrailer) may be called multiple times, save functions with guards and
sync blocks
Muxer MUST NOT changed packet content somehow, data, stream index, pts, dts,
duration, etc. because packets are shared with other muxers. If packet
content changes, other muxer cannot do their job correctly.
Muxers generally run in multi-thread environment so that writePacket
functions can be called by different thread at the same time. Protect
writePacket with synchronized keyword
- Author:
- mekya
-
Nested Class Summary
Modifier and TypeClassDescriptionstatic class
This class is used generally to send direct video buffer to muxer -
Field Summary
Modifier and TypeFieldDescriptionprivate boolean
private IAntMediaStreamHandler
private long
protected org.bytedeco.ffmpeg.avcodec.AVPacket
static final org.bytedeco.ffmpeg.avutil.AVRational
static final String
static final String
protected Set<org.bytedeco.ffmpeg.avcodec.AVBSFContext>
protected List<org.bytedeco.ffmpeg.avcodec.AVBSFContext>
Bitstream filter name that will be applied to packetsprivate long
private long
static final String
protected String
protected File
protected long
protected boolean
By default first video key frame are not checked, so it's true.private long
protected long
protected String
protected boolean
protected String
This is the initial original resource name without any suffix such _1, _2, or .mp4, .webmprotected boolean
protected AtomicBoolean
private long
protected org.slf4j.Logger
protected static org.slf4j.Logger
protected org.bytedeco.ffmpeg.avutil.AVDictionary
protected org.bytedeco.ffmpeg.avformat.AVFormatContext
private int
height of the resolutionprotected int
protected IScope
static final int
ts and m4s files index lengthprivate long
protected String
protected String
static final String
protected int
protected org.bytedeco.ffmpeg.avcodec.AVPacket
private long
protected io.vertx.core.Vertx
private int
protected byte[]
protected int
private long
protected org.bytedeco.ffmpeg.avcodec.AVPacket
protected int
-
Constructor Summary
-
Method Summary
Modifier and TypeMethodDescriptionboolean
addAudioStream
(int sampleRate, org.bytedeco.ffmpeg.avutil.AVChannelLayout channelLayout, int codecId, int streamIndex) Add audio stream to the muxer.void
addExtradataIfRequired
(org.bytedeco.ffmpeg.avcodec.AVPacket pkt, boolean isKeyFrame) boolean
addStream
(org.bytedeco.ffmpeg.avcodec.AVCodecParameters codecParameters, org.bytedeco.ffmpeg.avutil.AVRational timebase, int streamIndex) Add stream to the muxer.boolean
addStream
(org.bytedeco.ffmpeg.avcodec.AVCodec codec, org.bytedeco.ffmpeg.avcodec.AVCodecContext codecContext, int streamIndex) Add a new stream with this codec, codecContext and stream Index parameters.boolean
addVideoStream
(int width, int height, org.bytedeco.ffmpeg.avutil.AVRational timebase, int codecId, int streamIndex, boolean isAVC, org.bytedeco.ffmpeg.avcodec.AVCodecParameters codecpar) Add video stream to the muxer with direct parameters.org.bytedeco.ffmpeg.avformat.AVStream
avNewStream
(org.bytedeco.ffmpeg.avformat.AVFormatContext context) boolean
checkToDropPacket
(org.bytedeco.ffmpeg.avcodec.AVPacket pkt, int codecType) Return decision about dropping packet or notprotected void
void
contextChanged
(org.bytedeco.ffmpeg.avcodec.AVCodecContext codecContext, int streamIndex) It's called when the codecContext for the stream index has changed.void
contextWillChange
(org.bytedeco.ffmpeg.avcodec.AVCodecContext codecContext, int streamIndex) This is called when the current context will change/deleted soon.private String
extractCustomText
(String fileNameFormat) long
long
long
static long
getDurationInMs
(File f, String streamId) static long
getDurationInMs
(String url, String streamId) static String
getErrorDefinition
(int errorCode) getExtendedName
(String name, int resolution, int bitrate, String fileNameFormat) getFile()
long
org.bytedeco.ffmpeg.avutil.AVDictionary
abstract org.bytedeco.ffmpeg.avformat.AVFormatContext
getPacketBufferWithExtradata
(byte[] extradata, org.bytedeco.ffmpeg.avcodec.AVPacket pkt) static File
getPreviewFile
(IScope scope, String name, String extension) static File
getRecordFile
(IScope scope, String name, String extension, String subFolder) int
getResourceFile
(IScope scope, String name, String extension, String subFolder) org.bytedeco.ffmpeg.avcodec.AVPacket
static File
getUserRecordFile
(IScope scope, String userVoDFolder, String name) int
int
long
int
void
init
(IScope scope, String name, int resolution, boolean overrideIfExist, String subFolder, int bitrate) Init file name file format is NAME[-{DATETIME}][_{RESOLUTION_HEIGHT}p_{BITRATE}kbps].{EXTENSION} Datetime format is yyyy-MM-dd_HH-mm We are using "-" instead of ":" in HH:mm -> Stream filename must not contain ":" character.void
Inits the file to write.org.bytedeco.ffmpeg.avcodec.AVBSFContext
initAudioBitstreamFilter
(String bsfAudioName, org.bytedeco.ffmpeg.avcodec.AVCodecParameters codecParameters, org.bytedeco.ffmpeg.avutil.AVRational timebase) private org.bytedeco.ffmpeg.avcodec.AVBSFContext
initBitstreamFilter
(String bsfVideoName, org.bytedeco.ffmpeg.avcodec.AVCodecParameters codecParameters, org.bytedeco.ffmpeg.avutil.AVRational timebase) org.bytedeco.ffmpeg.avcodec.AVBSFContext
initVideoBitstreamFilter
(String bsfVideoName, org.bytedeco.ffmpeg.avcodec.AVCodecParameters codecParameters, org.bytedeco.ffmpeg.avutil.AVRational timebase) boolean
abstract boolean
isCodecSupported
(int codecId) void
logPacketIssue
(String format, Object... arguments) boolean
openIO()
boolean
This function may be called by multiple encoders.static String
void
setAddDateTimeToSourceName
(boolean addDateTimeToSourceName) void
setAudioBitreamFilter
(String bsfName) void
setBitstreamFilter
(String bsfName) void
setCurrentVoDTimeStamp
(long currentVoDTimeStamp) void
setIsRunning
(AtomicBoolean isRunning) void
void
setSubfolder
(String subFolder) void
writeAudioBuffer
(ByteBuffer audioFrame, int streamIndex, long timestamp) protected void
writeAudioFrame
(org.bytedeco.ffmpeg.avcodec.AVPacket pkt, org.bytedeco.ffmpeg.avutil.AVRational inputTimebase, org.bytedeco.ffmpeg.avutil.AVRational outputTimebase, org.bytedeco.ffmpeg.avformat.AVFormatContext context, long dts) void
writeDataFrame
(org.bytedeco.ffmpeg.avcodec.AVPacket pkt, org.bytedeco.ffmpeg.avformat.AVFormatContext context) boolean
void
writeMetaData
(String data, long dts) void
writePacket
(org.bytedeco.ffmpeg.avcodec.AVPacket pkt, org.bytedeco.ffmpeg.avcodec.AVCodecContext codecContext) Write packets to the output.void
writePacket
(org.bytedeco.ffmpeg.avcodec.AVPacket pkt, org.bytedeco.ffmpeg.avformat.AVStream stream) Write packets to the output.protected void
writePacket
(org.bytedeco.ffmpeg.avcodec.AVPacket pkt, org.bytedeco.ffmpeg.avutil.AVRational inputTimebase, org.bytedeco.ffmpeg.avutil.AVRational outputTimebase, int codecType) All other writePacket functions call this function to make the jobvoid
This function may be called by multiple encoders.void
writeVideoBuffer
(Muxer.VideoBuffer buffer) void
writeVideoBuffer
(ByteBuffer encodedVideoFrame, long dts, int frameRotation, int streamIndex, boolean isKeyFrame, long firstFrameTimeStamp, long pts) protected void
writeVideoFrame
(org.bytedeco.ffmpeg.avcodec.AVPacket pkt, org.bytedeco.ffmpeg.avformat.AVFormatContext context)
-
Field Details
-
BITSTREAM_FILTER_HEVC_MP4TOANNEXB
- See Also:
-
BITSTREAM_FILTER_H264_MP4TOANNEXB
- See Also:
-
currentVoDTimeStamp
private long currentVoDTimeStamp -
extension
-
format
-
isInitialized
protected boolean isInitialized -
options
-
logger
protected org.slf4j.Logger logger -
loggerStatic
protected static org.slf4j.Logger loggerStatic -
outputFormatContext
protected org.bytedeco.ffmpeg.avformat.AVFormatContext outputFormatContext -
DATE_TIME_PATTERN
- See Also:
-
file
-
vertx
protected io.vertx.core.Vertx vertx -
scope
-
addDateTimeToResourceName
private boolean addDateTimeToResourceName -
isRunning
-
videoExtradata
protected byte[] videoExtradata -
TEMP_EXTENSION
- See Also:
-
time2log
protected int time2log -
audioPkt
protected org.bytedeco.ffmpeg.avcodec.AVPacket audioPkt -
registeredStreamIndexList
-
bsfVideoNames
Bitstream filter name that will be applied to packets -
bsfAudioNames
-
streamId
-
inputTimeBaseMap
-
bsfFilterContextList
-
bsfAudioFilterContextList
-
videoWidth
protected int videoWidth -
videoHeight
protected int videoHeight -
headerWritten
protected volatile boolean headerWritten -
initialResourceNameWithoutExtension
This is the initial original resource name without any suffix such _1, _2, or .mp4, .webm -
tmpPacket
protected org.bytedeco.ffmpeg.avcodec.AVPacket tmpPacket -
firstAudioDts
protected long firstAudioDts -
firstVideoDts
protected long firstVideoDts -
videoPkt
protected org.bytedeco.ffmpeg.avcodec.AVPacket videoPkt -
rotation
protected int rotation -
SEGMENT_INDEX_LENGTH
public static final int SEGMENT_INDEX_LENGTHts and m4s files index length- See Also:
-
inputOutputStreamIndexMap
-
resolution
private int resolutionheight of the resolution -
avRationalTimeBase
public static final org.bytedeco.ffmpeg.avutil.AVRational avRationalTimeBase -
subFolder
-
firstKeyFrameReceived
protected boolean firstKeyFrameReceivedBy default first video key frame are not checked, so it's true. If the first video key frame should be checked, make this setting to false. It's being used in RecordMuxer and HLSMuxer -
lastPts
private long lastPts -
optionDictionary
protected org.bytedeco.ffmpeg.avutil.AVDictionary optionDictionary -
firstPacketDtsMs
private long firstPacketDtsMs -
audioNotWrittenCount
private long audioNotWrittenCount -
videoNotWrittenCount
private long videoNotWrittenCount -
totalSizeInBytes
private long totalSizeInBytes -
startTimeInSeconds
private long startTimeInSeconds -
currentTimeInSeconds
private long currentTimeInSeconds -
videoCodecId
private int videoCodecId -
appInstance
-
-
Constructor Details
-
Muxer
protected Muxer(io.vertx.core.Vertx vertx)
-
-
Method Details
-
getPreviewFile
-
getRecordFile
-
getUserRecordFile
-
addStream
public boolean addStream(org.bytedeco.ffmpeg.avcodec.AVCodec codec, org.bytedeco.ffmpeg.avcodec.AVCodecContext codecContext, int streamIndex) Add a new stream with this codec, codecContext and stream Index parameters. After adding streams, need to call prepareIO() This method is called by encoder. After encoder is opened, it adds codec context to the muxer- Parameters:
codec
-codecContext
-streamIndex
-- Returns:
-
getOutputURL
-
openIO
public boolean openIO() -
prepareIO
public boolean prepareIO()This function may be called by multiple encoders. Make sure that it is called once. See the sample implementations how it is being protected Implement this function with synchronized keyword as the subclass- Returns:
-
writeHeader
public boolean writeHeader() -
writeTrailer
public void writeTrailer()This function may be called by multiple encoders. Make sure that it is called once. See the sample implementations how it is being protected Implement this function with synchronized keyword as the subclass -
clearResource
protected void clearResource() -
writePacket
public void writePacket(org.bytedeco.ffmpeg.avcodec.AVPacket pkt, org.bytedeco.ffmpeg.avformat.AVStream stream) Write packets to the output. This function is used in by MuxerAdaptor which is in community edition Check if outputContext.pb is not null for the ffmpeg base Muxers Implement this function with synchronized keyword as the subclass- Parameters:
pkt
- The content of the data as a AVPacket object
-
logPacketIssue
-
writePacket
public void writePacket(org.bytedeco.ffmpeg.avcodec.AVPacket pkt, org.bytedeco.ffmpeg.avcodec.AVCodecContext codecContext) Write packets to the output. This function is used in transcoding. Previously, It's the replacement of {link#writePacket(AVPacket)
- Parameters:
pkt
-codecContext
-
-
getPacketBufferWithExtradata
public ByteBuffer getPacketBufferWithExtradata(byte[] extradata, org.bytedeco.ffmpeg.avcodec.AVPacket pkt) -
setAudioBitreamFilter
-
getBsfAudioNames
-
setBitstreamFilter
-
getBitStreamFilter
-
getFile
-
getFileName
-
getFormat
-
init
Inits the file to write. Multiple encoders can init the muxer. It is redundant to init multiple times. -
init
public void init(IScope scope, String name, int resolution, boolean overrideIfExist, String subFolder, int bitrate) Init file name file format is NAME[-{DATETIME}][_{RESOLUTION_HEIGHT}p_{BITRATE}kbps].{EXTENSION} Datetime format is yyyy-MM-dd_HH-mm We are using "-" instead of ":" in HH:mm -> Stream filename must not contain ":" character. sample naming -> stream1-yyyy-MM-dd_HH-mm_480p_500kbps.mp4 if datetime is added stream1_480p.mp4 if no datetime- Parameters:
name
- , name of the streamscope
-resolution
- height of the stream, if it is zero, then no resolution will be added to resource nameoverrideIfExist
- whether override if a file exists with the same namebitrate
- bitrate of the stream, if it is zero, no bitrate will be added to resource name
-
setSubfolder
-
getAppSettings
-
getAppAdaptor
-
getExtendedName
-
extractCustomText
-
getResourceFile
-
isAddDateTimeToSourceName
public boolean isAddDateTimeToSourceName() -
setAddDateTimeToSourceName
public void setAddDateTimeToSourceName(boolean addDateTimeToSourceName) -
addVideoStream
public boolean addVideoStream(int width, int height, org.bytedeco.ffmpeg.avutil.AVRational timebase, int codecId, int streamIndex, boolean isAVC, org.bytedeco.ffmpeg.avcodec.AVCodecParameters codecpar) Add video stream to the muxer with direct parameters. This method is called when there is a WebRTC ingest and there is no adaptive streaming- Parameters:
width
- , video widthheight
- , video heightcodecId
- , codec id of the streamstreamIndex
- , stream indexisAVC
- , true if packets are in AVC format, false if in annexb format- Returns:
- true if successful, false if failed
-
addAudioStream
public boolean addAudioStream(int sampleRate, org.bytedeco.ffmpeg.avutil.AVChannelLayout channelLayout, int codecId, int streamIndex) Add audio stream to the muxer.- Parameters:
sampleRate
-channelLayout
-codecId
-streamIndex
- , is the stream index of source- Returns:
-
avNewStream
public org.bytedeco.ffmpeg.avformat.AVStream avNewStream(org.bytedeco.ffmpeg.avformat.AVFormatContext context) -
addStream
public boolean addStream(org.bytedeco.ffmpeg.avcodec.AVCodecParameters codecParameters, org.bytedeco.ffmpeg.avutil.AVRational timebase, int streamIndex) Add stream to the muxer. This method is called by direct muxing. For instance from RTMP, SRT ingest & Stream Pull to HLS, MP4, HLS, DASH WebRTC Muxing- Parameters:
codecParameters
-timebase
-streamIndex
- , is the stream index of the source. Sometimes source and target stream index do not match- Returns:
-
initAudioBitstreamFilter
public org.bytedeco.ffmpeg.avcodec.AVBSFContext initAudioBitstreamFilter(String bsfAudioName, org.bytedeco.ffmpeg.avcodec.AVCodecParameters codecParameters, org.bytedeco.ffmpeg.avutil.AVRational timebase) -
initVideoBitstreamFilter
public org.bytedeco.ffmpeg.avcodec.AVBSFContext initVideoBitstreamFilter(String bsfVideoName, org.bytedeco.ffmpeg.avcodec.AVCodecParameters codecParameters, org.bytedeco.ffmpeg.avutil.AVRational timebase) -
initBitstreamFilter
private org.bytedeco.ffmpeg.avcodec.AVBSFContext initBitstreamFilter(String bsfVideoName, org.bytedeco.ffmpeg.avcodec.AVCodecParameters codecParameters, org.bytedeco.ffmpeg.avutil.AVRational timebase) -
writeVideoBuffer
public void writeVideoBuffer(ByteBuffer encodedVideoFrame, long dts, int frameRotation, int streamIndex, boolean isKeyFrame, long firstFrameTimeStamp, long pts) -
writeVideoBuffer
-
writeAudioBuffer
-
getRegisteredStreamIndexList
-
setIsRunning
-
setOption
-
getOptionDictionary
public org.bytedeco.ffmpeg.avutil.AVDictionary getOptionDictionary() -
isCodecSupported
public abstract boolean isCodecSupported(int codecId) -
getOutputFormatContext
public abstract org.bytedeco.ffmpeg.avformat.AVFormatContext getOutputFormatContext() -
checkToDropPacket
public boolean checkToDropPacket(org.bytedeco.ffmpeg.avcodec.AVPacket pkt, int codecType) Return decision about dropping packet or not- Parameters:
pkt
-codecType
-- Returns:
- true to drop the packet, false to not drop packet
-
getVideoWidth
public int getVideoWidth() -
getVideoHeight
public int getVideoHeight() -
getAverageBitrate
public long getAverageBitrate() -
writePacket
protected void writePacket(org.bytedeco.ffmpeg.avcodec.AVPacket pkt, org.bytedeco.ffmpeg.avutil.AVRational inputTimebase, org.bytedeco.ffmpeg.avutil.AVRational outputTimebase, int codecType) All other writePacket functions call this function to make the job- Parameters:
pkt
- Content of the data in AVPacket classinputTimebase
- input time base is required to calculate the correct dts and pts values for the containeroutputTimebase
- output time base is required to calculate the correct dts and pts values for the container
-
writeDataFrame
public void writeDataFrame(org.bytedeco.ffmpeg.avcodec.AVPacket pkt, org.bytedeco.ffmpeg.avformat.AVFormatContext context) -
addExtradataIfRequired
public void addExtradataIfRequired(org.bytedeco.ffmpeg.avcodec.AVPacket pkt, boolean isKeyFrame) -
writeVideoFrame
protected void writeVideoFrame(org.bytedeco.ffmpeg.avcodec.AVPacket pkt, org.bytedeco.ffmpeg.avformat.AVFormatContext context) -
writeAudioFrame
protected void writeAudioFrame(org.bytedeco.ffmpeg.avcodec.AVPacket pkt, org.bytedeco.ffmpeg.avutil.AVRational inputTimebase, org.bytedeco.ffmpeg.avutil.AVRational outputTimebase, org.bytedeco.ffmpeg.avformat.AVFormatContext context, long dts) -
getDurationInMs
-
getDurationInMs
- Parameters:
url
-streamId
-- Returns:
- -1 if duration is not available in the stream -2 if input is not opened -3 if stream info is not found
-
getErrorDefinition
-
contextWillChange
public void contextWillChange(org.bytedeco.ffmpeg.avcodec.AVCodecContext codecContext, int streamIndex) This is called when the current context will change/deleted soon. It's called by encoder and likely due to aspect ratio change After this method has been called, this methodcontextChanged(AVCodecContext, int)
should be called- Parameters:
codecContext
- the current context that will be changed/deleted soonstreamIndex
-
-
contextChanged
public void contextChanged(org.bytedeco.ffmpeg.avcodec.AVCodecContext codecContext, int streamIndex) It's called when the codecContext for the stream index has changed.contextWillChange(AVCodecContext, int)
is called before this method is called.- Parameters:
codecContext
-streamIndex
-
-
getInputTimeBaseMap
-
getTmpPacket
public org.bytedeco.ffmpeg.avcodec.AVPacket getTmpPacket() -
getIsRunning
-
getCurrentVoDTimeStamp
public long getCurrentVoDTimeStamp() -
setCurrentVoDTimeStamp
public void setCurrentVoDTimeStamp(long currentVoDTimeStamp) -
getResolution
public int getResolution() -
getLastPts
public long getLastPts() -
replaceDoubleSlashesWithSingleSlash
-
getVideoNotWrittenCount
public long getVideoNotWrittenCount() -
getAudioNotWrittenCount
public long getAudioNotWrittenCount() -
writeMetaData
-
getVideoCodecId
public int getVideoCodecId() -
getSubFolder
-