我正在开发一个 C# 程序,用于将所有元数据从一个 MP4 文件传输到另一个文件。我正在使用 Microsoft.WindowsAPICodePack.Shell 库来实现此目的。该程序成功传输了大多数元数据属性。但是,当我使用 mediainfo 实用程序检查元数据时,我注意到“标记日期”属性未传输且保持不变。我在 SystemProperties.System.* 中找不到此属性。我还尝试迭代名称中包含“日期”的属性,并将它们设置为特定日期,以查看“标记日期”是否会更改,但这并没有发生。
我尝试手动设置与日期相关的属性,看看是否会影响“标记日期”,但没有成功。我还发现这个值是由某些程序在创建视频文件时设置的,但我仍然无法更改它的值。我也尝试通过HxD搜索与日期对应的字节,但找不到
我找到了解决办法,直接修改MP4文件的字节数据。以下 C# 代码演示了如何在 MP4 文件中查找和替换与“标记日期”属性关联的字节。
using System;
using System.IO;
using System.Linq;
class Program
{
static void Main(string[] args)
{
string filePath = "./input.mp4";
byte[] searchPattern = { 0x6D, 0x76, 0x68, 0x64 }; // 'mvhd' header pattern in MP4 files
string dateString = "2012-02-06 06:26:50"; //example date
byte[] replacementData = GetReplacementData(dateString);
ReplaceBytes(filePath, searchPattern, replacementData);
}
static byte[] GetReplacementData(string dateString)
{
DateTime date = DateTime.Parse(dateString);
long time = new DateTimeOffset(date).ToUnixTimeSeconds() + 2082844800;
byte[] replacementData = BitConverter.GetBytes(time).Take(4).ToArray();
if (BitConverter.IsLittleEndian)
{
Array.Reverse(replacementData);
}
return replacementData;
}
static void ReplaceBytes(string filePath, byte[] searchPattern, byte[] replacementData)
{
byte[] fileData = File.ReadAllBytes(filePath);
bool found = false;
for (int i = 0; i < fileData.Length - 20; i++)
{
bool match = true;
for (int j = 0; j < searchPattern.Length; j++)
{
if (fileData[i + j] != searchPattern[j])
{
match = false;
break;
}
}
if (match)
{
found = true;
int offset = i + searchPattern.Length + 8;
Array.Copy(replacementData, 0, fileData, offset, replacementData.Length);
break;
}
}
if (!found)
{
Console.WriteLine("Search pattern not found.");
return;
}
File.WriteAllBytes(filePath, fileData);
Console.WriteLine("Bytes replaced successfully.");
}
}