protected override bool FeedMetaData(MediaFile pFile, MediaFrame mediaFrame) { //1. Seek into the data file at the correct position if (!pFile.SeekTo(mediaFrame.Start)) { FATAL("Unable to seek to position {0}", mediaFrame.Start); return(false); } var endPosition = pFile.Position + (long)mediaFrame.Length; //2. Read the data //_metadataBuffer.IgnoreAll(); //if (!_metadataBuffer.ReadFromFs(pFile, (int) mediaFrame.Length)) { // Logger.FATAL("Unable to read {0} bytes from offset {1}", mediaFrame.Length, mediaFrame.Start); // return false; //} //3. Parse the metadata _metadataName = ""; _metadataParameters.SetValue(); var _tempVariant = _amf0Reader.ReadVariant(); //if (!_amfSerializer.Read(_metadataBuffer, _tempVariant)) { // Logger.WARN("Unable to read metadata"); // return true; //} if (_tempVariant != VariantType.String) { WARN("Unable to read metadata"); return(true); } _metadataName = _tempVariant; while (pFile.Position < endPosition) { _metadataParameters.Add(_amf0Reader.ReadVariant()); } var message = GenericMessageFactory.GetNotify( ((BaseOutNetRTMPStream )OutStreams.Last()).CommandsChannelId, ((BaseOutNetRTMPStream )OutStreams.Last()).RTMPStreamId, mediaFrame.AbsoluteTime, true, _metadataName, _metadataParameters); //5. Send it return(((BaseRTMPProtocol )Protocol).SendMessage(message, true)); }
public override void ReadyForSend() { lock (this) { if (!Feed()) { Logger.FATAL("Feed failed"); if (OutStreams.Any()) { OutStreams.Last().EnqueueForDelete(); } } else { Flush(); } } }
protected override bool FeedOtherType() { if (_currentFrame.Type == MediaFrameType.Message && OutStreams.Last() is BaseOutNetRTMPStream) { if (!_pFile.SeekTo(_currentFrame.Start)) { FATAL("Unable to seek to position {0}", _currentFrame.Start); return(false); } var buffer = new BufferWithOffset(_amf0Reader.BaseStream, false, (int)_currentFrame.Length); SendStreamMessage(buffer); _pFile.Position = _currentFrame.Start + _currentFrame.Length; //message.Recycle(); _currentFrameIndex++; return(true); } //todo 这里会导致播放中断,对于其他协议要修改 Paused = true; return(base.FeedOtherType()); }
protected virtual bool Feed() { //2. First, send audio and video codecs if (!_audioVideoCodecsSent && !SendCodecs()) { Logger.FATAL("Unable to send audio codec"); return(false); } while (!Paused && OutStreams.Count != 0) { //2. Determine if the client has enough data on the buffer and continue //or stay put var elapsedTime = (int)(DateTime.Now - _startFeedingTime).TotalSeconds; if ((int)_totalSentTime - elapsedTime >= _clientSideBufferLength) { return(true); } //3. Test to see if we have sent the last frame if (_currentFrameIndex >= _totalFrames || _playLimit >= 0 && _playLimit < _totalSentTime) { this.Log().Info("Done streaming file"); OutStreams.Last().SignalStreamCompleted(); Paused = true; return(true); } //4. Read the current frame from the seeking file if (!_pSeekFile.SeekTo(_framesBaseOffset + _currentFrameIndex * MediaFrame.MediaFrameSize)) { Logger.FATAL("Unablt to seek inside seek file"); return(false); } if (!MediaFrame.ReadFromMediaFile(_pSeekFile, out _currentFrame)) { Logger.FATAL("Unable to read frame from seeking file"); return(false); } Stream buffer = null; //Debug.WriteLine("{2},{0}:{1}", _currentFrame.AbsoluteTime, _currentFrame.Type, _currentFrameIndex); switch (_currentFrame.Type) { case MediaFrameType.Data: _currentFrameIndex++; if (!FeedMetaData(_pFile, _currentFrame)) { Logger.FATAL("Unable to feed metadata"); return(false); } break; case MediaFrameType.Audio: buffer = _audioBuffer; goto case MediaFrameType.Video; case MediaFrameType.Video: if (buffer == null) { buffer = _videoBuffer; } //7. Build the frame if (!BuildFrame(_pFile, _currentFrame, buffer)) { Logger.FATAL("Unable to build the frame"); return(false); } //8. Compute the timestamp _totalSentTime = _currentFrame.AbsoluteTime / 1000 - _totalSentTimeBase; //9. Do the feedeng FeedData(buffer, (uint)buffer.Length, 0, (uint)buffer.Length, _currentFrame.AbsoluteTime, _currentFrame.Type == MediaFrameType.Audio); //10. Discard the data buffer.IgnoreAll(); //11. Increment the frame index _currentFrameIndex++; //12. Done. We either feed again if frame length was 0 //or just return true //return _currentFrame.Length != 0 || Feed(); break; default: if (!FeedOtherType()) { return(false); } break; } } return(true); }