新聞速報

        

2024年5月17日 星期五

判斷 mp4檔案 是否損壞?

判斷 mp4檔案 是否損壞?

 
static bool MP4_Checker(string filePath, out double LossRatePercentage)
{
    System.Diagnostics.Debug.WriteLine($" ");
 
    bool Ret = false;
 
    ulong FileSize = 0;
    ulong total_BoxSize = 0;
 
    LossRatePercentage = 100;   //預設 100% 遺失
 
 
    //FileStream BinaryReader:用於讀取檔案的二進制資料。
    using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
    {
        FileSize = (ulong)fs.Length;
        System.Diagnostics.Debug.WriteLine($"file Size: {FileSize}");
 
        if (FileSize == 0) return false;    //防呆
 
        //ReadMp4Boxes size  通過讀取 Box 的大小和類型來遍歷檔案中的每個 Box
        using (BinaryReader reader = new BinaryReader(fs))
        {
 
            while (reader.BaseStream.Position < reader.BaseStream.Length)
            {
                long boxStartPosition = reader.BaseStream.Position;
 
                // Read box size  每個 Box 的前 4 個位元組表示 Box 的大小
                uint boxSize = ReadUInt32(reader);
 
                // Read box type  每個 Box 的類型
                string boxType = ReadString(reader, 4);
 
                       
 
                // 每個 Box 的前 4 個位元組表示 Box 的大小。如果 Box 的大小為 1,表示使用擴展的 8 位元組大小
                if (boxSize == 1)
                {                           
                    ulong largeSize = ReadUInt64(reader);
                    System.Diagnostics.Debug.WriteLine($"Box Type: {boxType}, 擴展模式 Size: {largeSize}");
 
                    total_BoxSize += largeSize;
                    reader.BaseStream.Seek(boxStartPosition + (long)largeSize, SeekOrigin.Begin);
                }
                else if (boxSize == 0)
                {
                    // boxSize == 0 表示這個 Box 擴展到檔案末尾
                    total_BoxSize += (ulong)(reader.BaseStream.Length - reader.BaseStream.Position);
                    break; // 直接跳出循環
                }
                else
                {
                    System.Diagnostics.Debug.WriteLine($"Box Type: {boxType}, Size: {boxSize}");
 
                    total_BoxSize += boxSize;
                    reader.BaseStream.Seek(boxStartPosition + boxSize, SeekOrigin.Begin);
                }
            }
 
 
 
            // 通常 FileSize 小於等於 total_BoxSize
            //                           遺失數 / 總長度
            LossRatePercentage = (( total_BoxSize - FileSize ) / total_BoxSize) * 100;
 
            Ret = (FileSize == total_BoxSize);
 
            if (Ret == false)
            {
                Console.WriteLine($"FileSize:{FileSize}  total_BoxSize:{total_BoxSize}  差異:{(total_BoxSize - FileSize)}");
            }
        }
    }
 
    return Ret;
}
 
static uint ReadUInt32(BinaryReader reader)
{
    return (uint)IPAddress.NetworkToHostOrder(reader.ReadInt32());
}
 
static ulong ReadUInt64(BinaryReader reader)
{
    return (ulong)IPAddress.NetworkToHostOrder(reader.ReadInt64());
}
 
static string ReadString(BinaryReader reader, int length)
{
    byte[] bytes = reader.ReadBytes(length);
    return Encoding.UTF8.GetString(bytes);
}

沒有留言:

張貼留言