Beispiel #1
0
        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();
         }
     }
 }
Beispiel #3
0
 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);
        }