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); } }
/// <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(); }