public LivingStream GetLivingStream(string streamName) { if (publisherSessionService == null && serverTask != null) { var type = options.GetType(); var proInfo = type.GetProperty("ScopedServiceProvider", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); var serviceProvider = (IServiceProvider)proInfo.GetValue(options); publisherSessionService = serviceProvider.GetService <PublisherSessionService>(); } var _ = publisherSessionService ?? throw new InvalidOperationException("无法获取直播流"); return(publisherSessionService.FindPublisher(streamName)); }
public async Task Play( [FromOptionalArgument] string streamName, [FromOptionalArgument] double start = -1, [FromOptionalArgument] double duration = -1, [FromOptionalArgument] bool reset = false) { var publisher = _publisherSessionService.FindPublisher(streamName); if (publisher == null) { throw new KeyNotFoundException(); } var resetData = new AmfObject { { "level", "status" }, { "code", "NetStream.Play.Reset" }, { "description", "Resetting and playing stream." }, { "details", streamName } }; var resetStatus = RtmpSession.CreateCommandMessage <OnStatusCommandMessage>(); resetStatus.InfoObject = resetData; await MessageStream.SendMessageAsync(ChunkStream, resetStatus); var startData = new AmfObject { { "level", "status" }, { "code", "NetStream.Play.Start" }, { "description", "Started playing." }, { "details", streamName } }; var startStatus = RtmpSession.CreateCommandMessage <OnStatusCommandMessage>(); startStatus.InfoObject = startData; await MessageStream.SendMessageAsync(ChunkStream, startStatus); var flvMetadata = RtmpSession.CreateData <DataMessage>(); flvMetadata.MessageHeader = (MessageHeader)publisher.FlvMetadata.MessageHeader.Clone(); flvMetadata.Data = publisher.FlvMetadata.Data; await MessageStream.SendMessageAsync(ChunkStream, flvMetadata); _videoChunkStream = RtmpSession.CreateChunkStream(); _audioChunkStream = RtmpSession.CreateChunkStream(); if (publisher.AACConfigureRecord != null) { await MessageStream.SendMessageAsync(_audioChunkStream, publisher.AACConfigureRecord.Clone() as AudioMessage); } if (publisher.AVCConfigureRecord != null) { await MessageStream.SendMessageAsync(_videoChunkStream, publisher.AVCConfigureRecord.Clone() as VideoMessage); } publisher.OnAudioMessage += SendAudio; publisher.OnVideoMessage += SendVideo; _cleanupActions.Add(() => { publisher.OnVideoMessage -= SendVideo; publisher.OnAudioMessage -= SendAudio; }); }
public override async Task OnConnect() { var publisher = _publisherSessionService.FindPublisher(StreamName); if (publisher != null) { _cleanupActions.Add(() => { publisher.OnAudioMessage -= SendAudio; publisher.OnVideoMessage -= SendVideo; }); var metadata = (Dictionary <string, object>)publisher.FlvMetadata.Data.Last(); var hasAudio = metadata.ContainsKey("audiocodecid"); var hasVideo = metadata.ContainsKey("videocodecid"); await Session.SendFlvHeaderAsync(hasAudio, hasVideo); await Session.SendMessageAsync(publisher.FlvMetadata); if (hasAudio) { await Session.SendMessageAsync(publisher.AACConfigureRecord); } if (hasVideo) { await Session.SendMessageAsync(publisher.AVCConfigureRecord); } publisher.OnAudioMessage += SendAudio; publisher.OnVideoMessage += SendVideo; } // play record else { _recordFile = new FileStream(_recordService.GetRecordFilename(StreamName) + ".flv", FileMode.Open, FileAccess.Read); var fromStr = Query.Get("from"); long from = 0; if (fromStr != null) { from = long.Parse(fromStr); } var toStr = Query.Get("to"); _playRangeTo = -1; if (toStr != null) { _playRangeTo = long.Parse(toStr); } var header = new byte[9]; await _recordFile.ReadBytesAsync(header); await Session.SendRawDataAsync(header); from = Math.Max(from, 9); _recordFile.Seek(from, SeekOrigin.Begin); await PlayRecordFile(); } }