public override bool BuildFrame(MediaFile file, MediaFrame mediaFrame, Stream buffer) { if (mediaFrame.IsBinaryHeader) { buffer.Write(_videoCodecHeaderInit,0, _videoCodecHeaderInit.Length); } else { if (mediaFrame.IsKeyFrame) { // video key frame buffer.Write(_videoCodecHeaderKeyFrame, 0,_videoCodecHeaderKeyFrame.Length); } else { //video normal frame buffer.Write(_videoCodecHeader, 0, _videoCodecHeader.Length); } mediaFrame.CompositionOffset = IPAddress.HostToNetworkOrder(mediaFrame.CompositionOffset & 0x00ffffff) >> 8; buffer.Write(BitConverter.GetBytes(mediaFrame.CompositionOffset), 0, 3); } return base.BuildFrame(file, mediaFrame, buffer); }
public virtual bool BuildFrame(MediaFile file, MediaFrame mediaFrame, Stream buffer) { if (!file.SeekTo((long)mediaFrame.Start)) { FATAL("Unable to seek to position {0}", mediaFrame.Start); return false; } //3. Read the data file.DataStream.CopyPartTo(buffer, (int)mediaFrame.Length); buffer.Position = 0; return true; }
public override bool BuildFrame(MediaFile file, MediaFrame mediaFrame, Stream buffer) { //1. add the binary header if (mediaFrame.IsBinaryHeader) { buffer.Write(_audioCodecHeaderInit,0, _audioCodecHeaderInit.Length); } else { buffer.Write(_audioCodecHeader, 0, _audioCodecHeader.Length); } return base.BuildFrame(file, mediaFrame, buffer); }
public static bool ReadFromMediaFile(MediaFile file, out MediaFrame frame) { try { var bytes = new byte[MediaFrameSize]; file.ReadBuffer(bytes); bytes.GetStruct(out frame); } catch (Exception ex) { frame = new MediaFrame(); Logger.FATAL("cant't ReadFromMediaFile:{0}", ex); return(false); } return(true); }
public static bool ReadFromMediaFile(MediaFile file,out MediaFrame frame) { try { var bytes = new byte[MediaFrameSize]; file.ReadBuffer(bytes); bytes.GetStruct(out frame); } catch (Exception ex) { frame = new MediaFrame(); Logger.FATAL("cant't ReadFromMediaFile:{0}",ex); return false; } return true; }
public static int CompareFrames(MediaFrame frame1, MediaFrame frame2) { return((int)(frame1.AbsoluteTime == frame2.AbsoluteTime || (frame1.AbsoluteTime == 0 || frame2.AbsoluteTime == 0) ? frame1.Start - frame2.Start : frame1.AbsoluteTime - frame2.AbsoluteTime)); }
protected override bool BuildFrames() { //1. Build the map with frame sizes InitFrameSizes(); //2. Go to the beginning of the file if (!MediaFile.SeekBegin()) { Logger.FATAL("Unable to seek in file"); return false; } if (!ParseMetadata()) { Logger.WARN("Invalid metadata"); if (!FindFrameData()) { Logger.FATAL("Unable to position on frame data"); return false; } } var firstBytes = new byte[4]; double totalDuration = 0; var frame = new MediaFrame { Type = MediaFrameType.Audio, IsKeyFrame = true, DeltaTime = 0, IsBinaryHeader = false }; while (MediaFile.Position < MediaFile.Length) { //3. Read the first 4 bytes if (!MediaFile.ReadBuffer(firstBytes, 4)) { Logger.FATAL("Unable to read 4 byte"); return false; } if ((firstBytes[0] == 0xff) && ((firstBytes[1] >> 5) == 7)) { //4. Possible frame. Read the header byte version = (byte)((firstBytes[1] >> 3) & 0x03); byte layer = (byte)((firstBytes[1] >> 1) & 0x03); byte bitRateIndex = (byte)(firstBytes[2] >> 4); byte sampleRateIndex = (byte)((firstBytes[2] >> 2) & 0x03); byte paddingBit = (byte)((firstBytes[2] >> 1) & 0x01); //5. get the freame length frame.Start = (uint)(MediaFile.Position - 4); frame.Length = _frameSizes[version,layer,bitRateIndex,sampleRateIndex,paddingBit]; if (frame.Length == 0) { Logger.FATAL("Invalid frame length: {0}:{1}:{2}:{3}:{4}; Cusror: {5}", version, layer, bitRateIndex, sampleRateIndex, paddingBit, MediaFile.Position); return false; } //6. Compute the frame duration and save the frame start var samplesCount = layer == LAYER_1 ? 384 : 1152; frame.AbsoluteTime = (uint) (totalDuration * 1000); totalDuration += samplesCount / (double)(_samplingRates[version, sampleRateIndex]); //7. Seek to the next frame if (!MediaFile.SeekTo((long)(frame.Start + frame.Length))) { Logger.WARN("Unable to seek to {0}", frame.Start + frame.Length); break; } //8. All good. Save the frame _frames.Add(frame); } else { break; } } return true; }
public override bool BuildFrame(MediaFile file, MediaFrame mediaFrame, Stream buffer) { buffer.WriteByte(0x2f); return base.BuildFrame(file, mediaFrame, buffer); }
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); }
protected override bool BuildFrame(MediaFile pFile, MediaFrame mediaFrame, Stream buffer) { switch (mediaFrame.Type) { case MediaFrameType.Audio: return _pAudioBuilder == null || _pAudioBuilder.BuildFrame(pFile, mediaFrame, buffer); case MediaFrameType.Video: return _pVideoBuilder == null || _pVideoBuilder.BuildFrame(pFile, mediaFrame, buffer); default: return true; } }
public static int CompareFrames(MediaFrame frame1,MediaFrame frame2) { return (int) (frame1.AbsoluteTime == frame2.AbsoluteTime || (frame1.AbsoluteTime == 0 || frame2.AbsoluteTime == 0) ? frame1.Start - frame2.Start : frame1.AbsoluteTime - frame2.AbsoluteTime); }
protected override bool BuildFrames() { var binaryHeaders = new List<MediaFrame>(); //1. Go to the beginning of the file if (!MediaFile.SeekBegin()) { Logger.FATAL("Unable to seek in file"); return false; } //2. Ignore the flv header if (!MediaFile.SeekAhead(9)) { Logger.FATAL("Unable to seek in file"); return false; } //3. We are not interested in the previous tag size if (!MediaFile.SeekAhead(4)) { Logger.FATAL("Unable to seek in file"); return false; } //4. Build the frames while (MediaFile.Position != MediaFile.Length) { //5. Read the tag type byte tagType; if (!MediaFile.ReadUInt8(out tagType)) { Logger.WARN("Unable to read data"); break; } //6. Set the frame type based on the tag type //Also set the iskeyFrame property here var mustBreak = false; var frame = new MediaFrame(); switch (tagType) { case 8: //audio data _audioSamplesCount++; frame.Type = MediaFrameType.Audio; break; case 9: //video data _videoSamplesCount++; frame.Type = MediaFrameType.Video; break; case 15://message data frame.Type = MediaFrameType.Message; break; case 18: //info data frame.Type = MediaFrameType.Data; break; default: Logger.WARN("Invalid tag type: {0} at cursor {1}", tagType, MediaFile.Position); mustBreak = true; break; } if (mustBreak) break; //7. Read the frame length uint tempLength = MediaFile.Br.ReadU24(); //if (!MediaFile.ReadUInt24(out tempLength)) //{ // Logger.WARN("Unable to read data"); // break; //} frame.Length = tempLength; //8. read the timestamp and set the timing on the frame var timestamp = MediaFile.Br.ReadSU32(); //if (!MediaFile.ReadSUI32(out timestamp)) //{ // Logger.WARN("Unable to read data"); // break; //} //TODO: correctly compute delta time frame.DeltaTime = 0; frame.AbsoluteTime = timestamp; //9. Ignore the stream ID if (!MediaFile.SeekAhead(3)) { Logger.WARN("Unable to seek in file"); break; } //10. Save the start of the data frame.Start = (uint)MediaFile.Position; //11. Set the isKeyFrame flag and the isBinary flag byte _byte; switch (frame.Type) { case MediaFrameType.Video: if (!MediaFile.PeekByte(out _byte)) { Logger.FATAL("Unable to peek byte"); return false; } frame.IsKeyFrame = ((_byte >> 4) == 1); if (frame.IsKeyFrame) { frame.IsBinaryHeader = ((_byte & 0x0f) == 7); if (frame.IsBinaryHeader) { ulong dword; if (!MediaFile.PeekUInt64(out dword)) { Logger.FATAL("Unable to peek byte"); return false; } frame.IsBinaryHeader = (((dword >> 48) & 0xff) == 0); } } else { frame.IsBinaryHeader = false; } break; case MediaFrameType.Audio: frame.IsKeyFrame = true; if (!MediaFile.PeekByte(out _byte)) { Logger.FATAL("Unable to peek byte"); return false; } frame.IsBinaryHeader = ((_byte >> 4) == 10); if (frame.IsBinaryHeader) { ushort word; if (!MediaFile.PeekUInt16(out word)) { Logger.FATAL("Unable to peek byte"); return false; } frame.IsBinaryHeader = ((word & 0x00ff) == 0); } break; } if (frame.IsBinaryHeader) Logger.WARN("frame: {0}", frame); if (!MediaFile.SeekAhead(frame.Length)) { Logger.WARN("Unable to seek in file"); break; } //13. We are not interested in the previous tag size //if (!MediaFile.SeekAhead(4)) //{ // Logger.WARN("Unable to seek in file"); // break; //} var preTagSize = MediaFile.Br.ReadInt32(); //14. Store it in the proper location and adjust the timestamp accordingly //if (frame.IsBinaryHeader) //{ //frame.AbsoluteTime = 0; binaryHeaders.Insert(0, frame); //binaryHeaders.Add(frame); //} //else // { _frames.Add(frame); // } } //_frames.Sort(CompareFrames); //15. Add the binary headers //_frames.InsertRange(0, binaryHeaders); //for (var i = 0; i < binaryHeaders.Count; i++) { // _frames.Insert(0, binaryHeaders[i]); //} return true; }