Example #1
0
        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);
            }
        }
Example #2
0
        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);
        }