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 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); } } }
/// <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(); }
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); }
public ITagWriter GetAppendWriter() { // If the file doesnt exist, we cant append to it, so return a writer if (!_file.Exists) { #if !SILVERLIGHT log.Info("File does not exist, calling writer. This will create a new file."); #endif return GetWriter(); } //FileStream stream = _file.Open(FileMode.Append); FileStream stream = new FileStream(_file.FullName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read, 65536); ITagWriter writer = new FlvWriter(stream, true); return writer; }
public ITagWriter GetWriter() { if (_file.Exists) _file.Delete(); FileStream stream = _file.Create(); ITagWriter writer = new FlvWriter(stream, false); writer.WriteHeader(); return writer; }
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); } } }
/// <summary> /// Creates a new Flash screen video. /// </summary> /// <param name="parameters">The video parameters.</param> /// <exception cref="ArgumentNullException">Thrown if <paramref name="parameters"/> is null.</exception> public FlashScreenVideo(FlashScreenVideoParameters parameters) : base(parameters) { width = parameters.Width; height = parameters.Height; framesPerSecond = parameters.FramesPerSecond; nominalBlockWidth = parameters.BlockWidth; nominalBlockHeight = parameters.BlockHeight; keyFramePeriodInFrames = Math.Max(1, (int) Math.Ceiling(parameters.KeyFramePeriod.TotalSeconds * framesPerSecond)); cols = (width + nominalBlockWidth - 1) / nominalBlockWidth; rows = (height + nominalBlockHeight - 1) / nominalBlockHeight; int framePixelsLength = width * height; deflater = new Deflater(parameters.CompressionLevel, false); reserveBytesPerFrame = (nominalBlockHeight * nominalBlockWidth * 3 + 2 /*block header size*/ + ZLibWorstCaseInflation) * rows * cols + 4 /*frame header size*/; previousFramePixels = new int[framePixelsLength]; currentFramePixels = new int[framePixelsLength]; blockBuffer = new byte[nominalBlockHeight * nominalBlockWidth * 3]; flvWriter = new FlvWriter(FlvWriter.FlvFlags.Video); var flvMetadata = new FlvWriter.FlvMetadata() { { "duration", 0.0 }, { "width", width }, { "height", height }, { "framerate", framesPerSecond }, { "videocodecid", 3 /*screen video*/ }, { "canSeekToEnd", true } }; flvMetadataUpdater = flvWriter.WriteFlvMetaFrame(flvMetadata, 0); }