private void HandleNonObsStream(AbstractRtmpMediaMessage msg) { if (msg is VideoMessage) { VideoMessage vm = (VideoMessage)msg; if (vm.Timestamp != null) { vm.TimestampDelta = (vm.Timestamp - _videoTimestamp); _videoTimestamp = vm.Timestamp.Value; } else if (vm.TimestampDelta != null) { _videoTimestamp += vm.TimestampDelta.Value; vm.Timestamp = _videoTimestamp; } } if (msg is AudioMessage) { AudioMessage am = (AudioMessage)msg; if (am.Timestamp != null) { am.TimestampDelta = (am.Timestamp - _audioTimestamp); _audioTimestamp = am.Timestamp.Value; } else if (am.TimestampDelta != null) { _audioTimestamp += am.TimestampDelta.Value; am.Timestamp = _audioTimestamp; } } }
private void HandleMedia(IChannelHandlerContext ctx, AbstractRtmpMediaMessage msg) { var stream = _mediaStreamDic.GetValueOrDefault(_streamName); if (stream == null) { logger.Error($"stream:{nameof(_streamName)} not exist!"); return; } stream.AddContent(msg); }
public void AddContent(AbstractRtmpMediaMessage msg, bool isClient = false) { if (!isClient) { if (_streamName.IsObsClient) { HandleObsStream(msg); } else { HandleNonObsStream(msg); } } if (msg is VideoMessage) { VideoMessage vm = (VideoMessage)msg; if (vm.IsAVCDecoderConfigurationRecord()) { _avcDecoderConfigurationRecord = vm; } if (vm.IsH264KeyFrame()) { _content.Clear(); } } if (msg is AudioMessage) { AudioMessage am = (AudioMessage)msg; if (am.IsAACAudioSpecificConfig()) { _aacAudioSpecificConfig = am; } } _content.Add(msg); if (RtmpConfig.Instance.IsSaveFlvFile) { WriteFlv(msg); } BroadCastToSubscribers(msg); }
public async void BroadCastToSubscribers(AbstractRtmpMediaMessage msg) { var iterator = _subscribers.GetEnumerator(); foreach (var item in _subscribers) { if (item.Value.Active) { try { await item.Value.WriteAndFlushAsync(msg); } catch { } } else { _subscribers.Remove(item.Key, out IChannel channel); } } if (_httpFLvSubscribers.Count > 0) { byte[] encoded = EncodeMediaAsFlvTagAndPrevTagSize(msg); foreach (var item in _httpFLvSubscribers) { var wrappedBuffer = Unpooled.WrappedBuffer(encoded); if (item.Active) { await item.WriteAndFlushAsync(wrappedBuffer); } else { _httpFLvSubscribers.Remove(item); } } } }
private void HandleObsStream(AbstractRtmpMediaMessage msg) { if (msg.Timestamp != null) { _obsTimeStamp = msg.Timestamp; } else if (msg.TimestampDelta != null) { _obsTimeStamp += msg.TimestampDelta; } msg.Timestamp = _obsTimeStamp; if (msg is VideoMessage) { msg.TimestampDelta = (_obsTimeStamp - _videoTimestamp); _videoTimestamp = _obsTimeStamp; } if (msg is AudioMessage) { msg.TimestampDelta = (_obsTimeStamp - _audioTimestamp); _audioTimestamp = _obsTimeStamp; } }
private void WriteFlv(AbstractRtmpMediaMessage msg) { if (_flvOutput == null) { //logger.Error($"no flv file existed for stream : {_streamName}"); return; } try { if (!_flvHeadAndMetadataWritten) { WriteFlvHeaderAndMetadata(); _flvHeadAndMetadataWritten = true; } byte[] encodeMediaAsFlv = EncodeMediaAsFlvTagAndPrevTagSize(msg); _flvOutput.Write(encodeMediaAsFlv); _flvOutput.Flush(); } catch (IOException e) { logger.Error($"stream:{_streamName} writting flv file failed", e); } }
private byte[] EncodeMediaAsFlvTagAndPrevTagSize(AbstractRtmpMediaMessage msg) { int tagType = msg.GetMsgType(); byte[] data = msg.Raw(); int dataSize = data.Length; int timestamp = (msg.Timestamp ?? 0) & 0xffffff; int timestampExtended = (int)(((msg.Timestamp ?? 0) & 0xff000000) >> 24); var buffer = Unpooled.Buffer(); buffer.WriteByte(tagType); buffer.WriteMedium(dataSize); buffer.WriteMedium(timestamp); buffer.WriteByte(timestampExtended); // timestampExtended buffer.WriteMedium(0); // streamid buffer.WriteBytes(data); buffer.WriteInt(data.Length + 11); // prevousTagSize byte[] r = new byte[buffer.ReadableBytes]; buffer.ReadBytes(r); return(r); }