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
        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);
                    }
                }
        }
Example #3
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();
		}
Example #4
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);
        }
Example #5
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;
		}
Example #6
0
		public ITagWriter GetWriter() {
			if (_file.Exists)
				_file.Delete();
			FileStream stream = _file.Create();
			ITagWriter writer = new FlvWriter(stream, false);
			writer.WriteHeader();
			return writer;
		}
Example #7
0
        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);
        }