public Flv(FileInfo file, bool generateMetadata) { _file = file; _generateMetadata = generateMetadata; int count = 0; if (!_generateMetadata) { try { FlvReader reader = new FlvReader(_file); ITag tag = null; while (reader.HasMoreTags() && (++count < 5)) { tag = reader.ReadTag(); if (tag.DataType == IOConstants.TYPE_METADATA) { if (_metaService == null) _metaService = new MetaService(_file); _metaData = _metaService.ReadMetaData(tag.Body); } } reader.Close(); } catch (Exception ex) { #if !SILVERLIGHT log.Error("An error occured looking for metadata:", ex); #endif } } }
public void ReadBackpointer_WhenStateIsBeforeTag_ThrowsInvalidOperationException() { // Arrange _flvReader = _flvReaderObjectMother.CreateFlvReaderWithTag(); // Act and assert. Assert.Throws<InvalidOperationException>(() => _flvReader.ReadBackpointer()); }
public void ReadBackpointer_WhenStateIsBeforeHeader_ThrowsInvalidOperationException() { // Arrange _flvReader = _flvReaderObjectMother.CreateFlvReaderWithHeader(); // Act and assert. Assert.Throws <InvalidOperationException>(() => _flvReader.ReadBackpointer()); }
public void ReadHeader_ReachedEndOfStream_ThrowsInvalidOperationException() { // Arrange _flvReader = _flvReaderObjectMother.CreateEmptyFlvReader(); // Act and assert. Assert.Throws <InvalidOperationException>(() => _flvReader.ReadHeader()); }
public void ReadBackpointer_ReachedEndOfStream_ThrowsInvalidOperationException() { // Arrange _flvReader = _flvReaderObjectMother.CreateEmptyFlvReader(); _flvReader.MoveToBeforeBackpointerState(); // Act and assert. Assert.Throws<InvalidOperationException>(() => _flvReader.ReadBackpointer()); }
private static int RunExtractAndReturnExitCode(LaunchOptions.Extract opts) { Quite = opts.Quite; using var flv_stream = File.Open(opts.InputPath, FileMode.Open, FileAccess.Read, FileShare.Read); var tags = FlvReader.ReadFlvFile(flv_stream, opts.TagNum + 1); if (tags.Length > opts.TagNum) { FlvTag tag = tags[opts.TagNum]; if (string.IsNullOrWhiteSpace(opts.OutputPath)) { var s = new MemoryStream(); if (tag.TagType == TagType.Script && !opts.Byte) { FlvWriter.WriteTagData(s, flv_stream, tag); s.Position = 0; var body = ScriptTagBody.Parse(s); Console.WriteLine(body.ToJson()); } else { FlvWriter.WriteTag(s, flv_stream, tag); var str = BitConverter.ToString(s.ToArray()).Replace("-", ""); str = string.Join('\n', str.SplitInParts(64)); Console.WriteLine(str); } return(0); } else { var fi = new FileInfo(opts.OutputPath); if (fi.Exists && !opts.Overwrite) { if (!Quite) { Console.WriteLine("文件已经存在,使用 --force 参数覆盖目标位置文件"); } return(1); } using var output = fi.Open(FileMode.Create, FileAccess.ReadWrite, FileShare.Read); FlvWriter.WriteTag(output, flv_stream, tag); return(0); } } else { if (!Quite) { Console.WriteLine($"文件中只有个 {tags.Length} Tag,而需要第 {opts.TagNum} 个 Tag"); } return(1); } }
public void ReadBackpointer_WhenStateIsBeforeBackpointer_ReturnsBackpointer() { // Arrange _flvReader = _flvReaderObjectMother.CreateFlvReaderWithBackpointer(); // Act var backpointer = _flvReader.ReadBackpointer(); // Assert Assert.NotNull(backpointer); }
public void ReadTag_WhenStateIsBeforeTag_ReturnsTag() { // Arrange _flvReader = _flvReaderObjectMother.CreateFlvReaderWithTag(); // Act var tag = _flvReader.ReadTag(); // Assert Assert.NotNull(tag); }
public void ReadHeader_WhenStateIsBeforeHeader_ReturnsHeader() { // Arrange _flvReader = _flvReaderObjectMother.CreateFlvReaderWithHeader(); // Act var header = _flvReader.ReadHeader(); // Assert Assert.NotNull(header); }
public void ReadTag_ReachedEndOfStream_ReturnsNull() { // Arrange _flvReader = _flvReaderObjectMother.CreateEmptyFlvReader(); _flvReader.MoveToBeforeTagState(); // Act var tag = _flvReader.ReadTag(); // Assert Assert.Null(tag); }
public void Download(string path) { if (path == null) { throw new ArgumentNullException("path"); } var drNuRtmpStream = _drNuRtmpStreamFactory.CreateDrNuRtmpStream(RtmpUri); drNuRtmpStream.Duration += (sender, args) => OnDuration(args); drNuRtmpStream.Elapsed += (sender, args) => OnElapsed(args); using (var flvReader = new FlvReader(drNuRtmpStream)) using (var flvWriter = new FlvWriter(_fileWrapper.Create(path))) { IFlvPart flvPart; while ((flvPart = flvReader.Read()) != null) { flvWriter.Write(flvPart); } } }
public ITagReader GetReader() { FlvReader reader = null; string fileName = _file.Name; if (_file.Exists) { #if !SILVERLIGHT if (log.IsDebugEnabled) log.Debug("File size: " + _file.Length); #endif reader = new FlvReader(_file, _generateMetadata); } else { #if !SILVERLIGHT log.Info("Creating new file: " + fileName); #endif using (FileStream fs = _file.Create()) { } _file.Refresh(); reader = new FlvReader(_file, _generateMetadata); } return reader; }
private static int RunParseAndReturnExitCode(LaunchOptions.Parse opts) { Quite = opts.Quite; var input = new FileInfo(opts.InputPath); if (!input.Exists) { if (!Quite) { Console.WriteLine("FLV 文件不存在"); } return(1); } var fib = new FileInfo(opts.FibPath); if (fib.Exists && !opts.Overwrite) { if (!Quite) { Console.WriteLine("fib 文件已经存在,使用 --force 参数覆盖目标位置文件"); } return(1); } using var flv_stream = input.Open(FileMode.Open, FileAccess.Read, FileShare.Read); if (!Quite) { Console.WriteLine("读取 FLV 文件中..."); } string hash; if (opts.SkipHash) { hash = string.Empty; } else { using var md5 = MD5.Create(); var bytes = md5.ComputeHash(flv_stream); flv_stream.Position = 0; hash = BitConverter.ToString(bytes).Replace("-", "").ToLowerInvariant(); } var tags = FlvReader.ReadFlvFile(flv_stream); if (!Quite) { Console.WriteLine("FLV 文件读取完毕,生成 fib 命令文件..."); } var file = new FlvInteractiveRebaseCommandFile { File = new FlvInteractiveRebaseCommandFile.FlvFile { Hash = hash, SkipHash = opts.SkipHash, Path = input.FullName } }; int index = 0; var memoryStream = new MemoryStream(); file.Tags.AddRange(tags.Select(input_tag => { FlvInteractiveRebaseCommandFile.FlvTag result; if (input_tag.TagType == TagType.Script) { memoryStream.SetLength(0); FlvWriter.WriteTagData(memoryStream, flv_stream, input_tag); memoryStream.Position = 0; var body = ScriptTagBody.Parse(memoryStream); var json = body.ToJson(); result = new FlvInteractiveRebaseCommandFile.FlvTag { Command = FlvInteractiveRebaseCommandFile.FlvTagCommand.Script, Index = index++, TimeStamp = TimeSpan.FromMilliseconds(input_tag.TimeStamp), Value = json, Size = input_tag.TagSize, Offset = input_tag.Position, Type = input_tag.TagType, Header = input_tag.Flag.HasFlag(TagFlag.Header), Keyframe = input_tag.Flag.HasFlag(TagFlag.Keyframe), }; } else { result = new FlvInteractiveRebaseCommandFile.FlvTag { Command = FlvInteractiveRebaseCommandFile.FlvTagCommand.Pick, Index = index++, TimeStamp = TimeSpan.FromMilliseconds(input_tag.TimeStamp), Size = input_tag.TagSize, Offset = input_tag.Position, Type = input_tag.TagType, Header = input_tag.Flag.HasFlag(TagFlag.Header), Keyframe = input_tag.Flag.HasFlag(TagFlag.Keyframe), }; } if (result.Type == TagType.Video && opts.ShowNalu) { var b = new byte[4]; flv_stream.Seek(result.Offset + 11, SeekOrigin.Begin); if ((flv_stream.ReadByte() & 0x0F) == 7 && flv_stream.ReadByte() == 1) { result.Nalus = new List <FlvInteractiveRebaseCommandFile.FlvNalu>(); var end = result.Offset + 11 + result.Size; flv_stream.Seek(3, SeekOrigin.Current); while (true) { if (4 != flv_stream.Read(b)) { break; } var size = BitConverter.ToUInt32(b.ToBE(), 0); var type = flv_stream.ReadByte() & 0b00011111; flv_stream.Seek(size - 1, SeekOrigin.Current); result.Nalus.Add(new FlvInteractiveRebaseCommandFile.FlvNalu { Size = size, Type = type }); if (flv_stream.Position == end) { break; } else if (flv_stream.Position > end) { Console.WriteLine($"Nalu Warning: out of range. Offset: {result.Offset}, Nalu No: {result.Nalus.Count + 1}, Pos: {flv_stream.Position}"); break; } } } } return(result); })); using (var writer = new StreamWriter(fib.Open(FileMode.Create, FileAccess.ReadWrite, FileShare.None), new UTF8Encoding(false))) { FlvInteractiveRebaseCommandFile.Serialize(writer, file); } if (!Quite) { Console.WriteLine("成功生成"); } return(0); }
/// <summary> /// Initiates writing of the Metadata. /// </summary> /// <param name="meta">Metadata to write.</param> public void Write(MetaData meta) { // Get cue points, FLV reader and writer MetaCue[] metaArr = meta.MetaCue; FlvReader reader = new FlvReader(_file, false); FlvWriter writer = new FlvWriter(_output, false); ITag tag = null; // Read first tag if (reader.HasMoreTags()) { tag = reader.ReadTag(); if (tag.DataType == IOConstants.TYPE_METADATA) { if (!reader.HasMoreTags()) throw new IOException("File we're writing is metadata only?"); } } meta.Duration = (double)reader.Duration / 1000; meta.VideoCodecId = reader.VideoCodecId; meta.AudioCodecId = reader.AudioCodecId; ITag injectedTag = InjectMetaData(meta, tag); injectedTag.PreviousTagSize = 0; tag.PreviousTagSize = injectedTag.BodySize; writer.WriteHeader(); writer.WriteTag(injectedTag); writer.WriteTag(tag); int cuePointTimeStamp = 0; int counter = 0; if (metaArr != null) { Array.Sort(metaArr); cuePointTimeStamp = GetTimeInMilliseconds(metaArr[0]); } while (reader.HasMoreTags()) { tag = reader.ReadTag(); // if there are cuePoints in the array if (counter < metaArr.Length) { // If the tag has a greater timestamp than the // cuePointTimeStamp, then inject the tag while (tag.Timestamp > cuePointTimeStamp) { injectedTag = InjectMetaCue(metaArr[counter], tag); writer.WriteTag(injectedTag); tag.PreviousTagSize = injectedTag.BodySize; // Advance to the next CuePoint counter++; if (counter > (metaArr.Length - 1)) { break; } cuePointTimeStamp = GetTimeInMilliseconds(metaArr[counter]); } } if (tag.DataType != IOConstants.TYPE_METADATA) { writer.WriteTag(tag); } } writer.Close(); }