Exemplo n.º 1
0
        public void FinallizeFile()
        {
            try
            {
                string filepath = GetFileName();
                using (var fs = new FileStream(filepath, FileMode.CreateNew, FileAccess.ReadWrite))
                {
                    fs.Write(FlvStreamProcessor.FLV_HEADER_BYTES, 0, FlvStreamProcessor.FLV_HEADER_BYTES.Length);
                    fs.Write(new byte[] { 0, 0, 0, 0, }, 0, 4);

                    Header.Meta["duration"]      = (Tags[Tags.Count - 1].TimeStamp - Tags[0].TimeStamp) / 1000d;
                    Header.Meta["lasttimestamp"] = (Tags[Tags.Count - 1].TimeStamp - Tags[0].TimeStamp);

                    var t = new FlvTag
                    {
                        TagType = TagType.DATA,
                        Data    = Header.ToBytes()
                    };
                    t.WriteTo(fs);

                    int offset = Tags[0].TimeStamp;

                    HTags.ForEach(tag => tag.WriteTo(fs));
                    Tags.ForEach(tag => tag.WriteTo(fs, offset));

                    logger.Info("剪辑已保存:{0}", Path.GetFileName(filepath));

                    fs.Close();
                }
                Tags.Clear();

                ClipFinalized?.Invoke(this, new ClipFinalizedArgs()
                {
                    ClipProcessor = this
                });
            }
            catch (Exception ex)
            {
                logger.Error(ex, "保存剪辑文件时出错");
            }
        }
        public void FinallizeFile()
        {
            if (!Finallized)
            {
                lock (_writelock)
                {
                    try
                    {
                        Metadata.Meta["duration"]      = MaxTimeStamp / 1000.0;
                        Metadata.Meta["lasttimestamp"] = (double)MaxTimeStamp;
                        byte[] metadata = Metadata.ToBytes();


                        // 13 for FLV header & "0th" tag size
                        // 11 for 1st tag header
                        _fs?.Seek(13 + 11, SeekOrigin.Begin);
                        _fs?.Write(metadata, 0, metadata.Length);
                    }
                    catch (Exception ex)
                    {
                        logger.Error(ex, "保存录制文件时出错");
                    }
                    finally
                    {
                        _fs?.Close();
                        _buffer.Close();
                        _data.Close();
                        Tags.Clear();

                        Finallized = true;

                        StreamFinalized?.Invoke(this, new StreamFinalizedArgs()
                        {
                            StreamProcessor = this
                        });
                    }
                }
            }
        }
        private void _TagCreated(FlvTag tag)
        {
            if (Metadata == null)
            {
                if (tag.TagType == TagType.DATA)
                {
                    _fs?.Write(FLV_HEADER_BYTES, 0, FLV_HEADER_BYTES.Length);
                    _fs?.Write(new byte[] { 0, 0, 0, 0, }, 0, 4);

                    Metadata = FlvMetadata.Parse(tag.Data);

                    // TODO: 添加录播姬标记、录制信息

                    tag.Data = Metadata.ToBytes();
                    tag.WriteTo(_fs);
                }
                else
                {
                    throw new Exception("onMetaData not found");
                }
            }
            else
            {
                if (!hasOffset)
                {
                    if (tag.TagType == TagType.VIDEO)
                    {
                        TagVideoCount++;
                        if (TagVideoCount < 2)
                        {
                            logger.Trace("第一个 Video Tag 时间戳 {0} ms", tag.TimeStamp);
                            HTags.Add(tag);
                        }
                        else
                        {
                            BaseTimeStamp = tag.TimeStamp;
                            hasOffset     = true;
                            logger.Trace("重设时间戳 {0} 毫秒", BaseTimeStamp);
                        }
                    }
                    else if (tag.TagType == TagType.AUDIO)
                    {
                        TagAudioCount++;
                        if (TagAudioCount < 2)
                        {
                            logger.Trace("第一个 Audio Tag 时间戳 {0} ms", tag.TimeStamp);
                            HTags.Add(tag);
                        }
                        else
                        {
                            BaseTimeStamp = tag.TimeStamp;
                            hasOffset     = true;
                            logger.Trace("重设时间戳 {0} 毫秒", BaseTimeStamp);
                        }
                    }
                }


                if (hasOffset)
                {
                    tag.TimeStamp -= BaseTimeStamp; // 修复时间戳
                    if (tag.TimeStamp < 0)
                    {
                        tag.TimeStamp = 0;
                    }
                    MaxTimeStamp = Math.Max(MaxTimeStamp, tag.TimeStamp);
                }
                else
                {
                    tag.TimeStamp = 0;
                }

                // 如果没有禁用 Clip 功能
                if (!_noClip)
                {
                    Tags.Add(tag); // Clip 缓存

                    // 移除过旧的数据
                    if (MaxTimeStamp - LasttimeRemovedTimestamp > 800)
                    {
                        LasttimeRemovedTimestamp = MaxTimeStamp;
                        int max_remove_index = Tags.FindLastIndex(x => x.IsVideoKeyframe && ((MaxTimeStamp - x.TimeStamp) > (Clip_Past * SEC_TO_MS)));
                        if (max_remove_index > 0)
                        {
                            Tags.RemoveRange(0, max_remove_index);
                        }
                        // Tags.RemoveRange(0, max_remove_index + 1 - 1);
                        // 给将来的备注:这里是故意 + 1 - 1 的,因为要保留选中的那个关键帧, + 1 就把关键帧删除了
                    }
                }

                // 写入硬盘
                tag.WriteTo(_fs);

                TagProcessed?.Invoke(this, new TagProcessedArgs()
                {
                    Tag = tag
                });
            } // if (Metadata == null) else
        }