Package io.antmedia.muxer
Class Muxer
java.lang.Object
io.antmedia.muxer.Muxer
- Direct Known Subclasses:
EndpointMuxer,HLSMuxer,RecordMuxer,RtmpProvider
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
Nested ClassesModifier and TypeClassDescriptionstatic classThis class is used generally to send direct video buffer to muxer -
Field Summary
FieldsModifier and TypeFieldDescriptionprivate booleanprivate IAntMediaStreamHandlerprivate longprotected org.bytedeco.ffmpeg.avcodec.AVPacketstatic final org.bytedeco.ffmpeg.avutil.AVRationalstatic final Stringstatic final Stringprotected Set<org.bytedeco.ffmpeg.avcodec.AVBSFContext>protected List<org.bytedeco.ffmpeg.avcodec.AVBSFContext>Bitstream filter name that will be applied to packetsprivate longprivate longstatic final Stringprotected Stringprotected Fileprotected longprotected booleanBy default first video key frame are not checked, so it's true.private longprotected longprotected Stringprotected booleanprotected StringOptional override for the initial resource name without extension.protected StringThis is the initial original resource name without any suffix such _1, _2, or .mp4, .webmprotected booleanprotected AtomicBooleanprivate longprotected org.slf4j.Loggerprotected static org.slf4j.Loggerprotected org.bytedeco.ffmpeg.avutil.AVDictionaryprotected org.bytedeco.ffmpeg.avformat.AVFormatContextprivate intheight of the resolutionprotected intprotected IScopestatic final intts and m4s files index lengthprivate longprotected Stringprotected Stringstatic final Stringprotected intprotected org.bytedeco.ffmpeg.avcodec.AVPacketprivate longprotected io.vertx.core.Vertxprivate intprotected byte[]protected intprivate longprotected org.bytedeco.ffmpeg.avcodec.AVPacketprotected int -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionbooleanaddAudioStream(int sampleRate, org.bytedeco.ffmpeg.avutil.AVChannelLayout channelLayout, int codecId, int streamIndex) Add audio stream to the muxer.voidaddExtradataIfRequired(org.bytedeco.ffmpeg.avcodec.AVPacket pkt, boolean isKeyFrame) booleanaddStream(org.bytedeco.ffmpeg.avcodec.AVCodecParameters codecParameters, org.bytedeco.ffmpeg.avutil.AVRational timebase, int streamIndex) Add stream to the muxer.booleanaddStream(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.booleanaddVideoStream(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.voidorg.bytedeco.ffmpeg.avformat.AVStreamavNewStream(org.bytedeco.ffmpeg.avformat.AVFormatContext context) booleancheckToDropPacket(org.bytedeco.ffmpeg.avcodec.AVPacket pkt, int codecType) Return decision about dropping packet or notprotected voidvoidcontextChanged(org.bytedeco.ffmpeg.avcodec.AVCodecContext codecContext, int streamIndex) t's called when the codecContext for the stream index has changed.voidcontextChanged(org.bytedeco.ffmpeg.avcodec.AVCodecContext codecContext, int streamIndex, int encoderHashCode) It's called when the codecContext for the stream index has changed.voidcontextWillChange(org.bytedeco.ffmpeg.avcodec.AVCodecContext codecContext, int streamIndex) This is called when the current context will change/deleted soon.voidcontextWillChange(org.bytedeco.ffmpeg.avcodec.AVCodecContext codecContext, int streamIndex, int encoderHashCode) This method is called when the current context will change/deleted soon.private StringextractCustomText(String fileNameFormat) longlongList<org.bytedeco.ffmpeg.avcodec.AVBSFContext>longstatic longgetDurationInMs(File f, String streamId) static longgetDurationInMs(String url, String streamId) static StringgetErrorDefinition(int errorCode) getExtendedName(String name, int resolution, int bitrate, String fileNameFormat) getFile()longorg.bytedeco.ffmpeg.avutil.AVDictionaryabstract org.bytedeco.ffmpeg.avformat.AVFormatContextgetPacketBufferWithExtradata(byte[] extradata, org.bytedeco.ffmpeg.avcodec.AVPacket pkt) static FilegetPreviewFile(IScope scope, String name, String extension) static FilegetRecordFile(IScope scope, String name, String extension, String subFolder) intgetResourceFile(IScope scope, String name, String extension, String subFolder) org.bytedeco.ffmpeg.avcodec.AVPacketstatic FilegetUserRecordFile(IScope scope, String userVoDFolder, String name) intbyte[]intlongintvoidinit(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.voidInits the file to write.org.bytedeco.ffmpeg.avcodec.AVBSFContextinitAudioBitstreamFilter(String bsfAudioName, org.bytedeco.ffmpeg.avcodec.AVCodecParameters codecParameters, org.bytedeco.ffmpeg.avutil.AVRational timebase) private org.bytedeco.ffmpeg.avcodec.AVBSFContextinitBitstreamFilter(String bsfVideoName, org.bytedeco.ffmpeg.avcodec.AVCodecParameters codecParameters, org.bytedeco.ffmpeg.avutil.AVRational timebase) org.bytedeco.ffmpeg.avcodec.AVBSFContextinitVideoBitstreamFilter(String bsfVideoName, org.bytedeco.ffmpeg.avcodec.AVCodecParameters codecParameters, org.bytedeco.ffmpeg.avutil.AVRational timebase) booleanabstract booleanisCodecSupported(int codecId) voidlogPacketIssue(String format, Object... arguments) booleanopenIO()booleanThis function may be called by multiple encoders.static StringvoidsetAddDateTimeToSourceName(boolean addDateTimeToSourceName) voidsetAudioBitreamFilter(String bsfName) voidsetBitstreamFilter(String bsfName) voidsetCurrentVoDTimeStamp(long currentVoDTimeStamp) voidvoidsetInitialResourceNameOverride(String baseName) voidsetIsRunning(AtomicBoolean isRunning) voidvoidsetStreamId(String streamId) voidsetSubfolder(String subFolder) voidwriteAudioBuffer(ByteBuffer audioFrame, int streamIndex, long timestamp) protected voidwriteAudioFrame(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) voidwriteDataFrame(org.bytedeco.ffmpeg.avcodec.AVPacket pkt, org.bytedeco.ffmpeg.avformat.AVFormatContext context) booleanvoidwriteMetaData(String data, long dts) voidwritePacket(org.bytedeco.ffmpeg.avcodec.AVPacket pkt, org.bytedeco.ffmpeg.avcodec.AVCodecContext codecContext) Write packets to the output.voidwritePacket(org.bytedeco.ffmpeg.avcodec.AVPacket pkt, org.bytedeco.ffmpeg.avformat.AVStream stream) Write packets to the output.voidwritePacket(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 jobvoidThis function may be called by multiple encoders.voidwriteVideoBuffer(Muxer.VideoBuffer buffer) voidwriteVideoBuffer(ByteBuffer encodedVideoFrame, long dts, int frameRotation, int streamIndex, boolean isKeyFrame, long firstFrameTimeStamp, long pts) protected voidwriteVideoFrame(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 -
initialResourceNameOverride
Optional override for the initial resource name without extension. If provided, it will be used directly for file naming instead of building a name viagetExtendedName(java.lang.String, int, int, java.lang.String). -
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
-
setFormat
-
getBsfFilterContextList
-
getPreviewFile
-
getVideoExtradata
public byte[] getVideoExtradata() -
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
-
allocateAVPacket
public void allocateAVPacket() -
setInitialResourceNameOverride
-
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
public 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, int encoderHashCode) This method is called when the current context will change/deleted soon.- Parameters:
codecContext-streamIndex-encoderHashCode- : Is the encoder's class object hash code that calls this method
-
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) t's called when the codecContext for the stream index has changed.- Parameters:
codecContext-streamIndex-encoderHashCode-
-
contextChanged
public void contextChanged(org.bytedeco.ffmpeg.avcodec.AVCodecContext codecContext, int streamIndex, int encoderHashCode) 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
-
setStreamId
-