Зведення
Це оновлення вирішує проблему кодування метаданих, через яку музичні файли Free Lossless Audio Codec (FLAC) стають непридатними для відтворення, якщо змінити їхню назву, виконавця або інші метадані.
Причина
Ця проблема може виникнути, якщо файли FLAC містять кадр ID3 перед заголовком FLAC. Кадр ID3 містить метадані, такі як назва та ім'я виконавця. Обробник властивостей FLAC припускав, що всі файли FLAC починаються з 4-байтового стартового коду fLaC і не враховують фрейм ID3 на початку файлу. Таким чином, фрейм ID3 буде перезаписано без початкового коду fLaC, що робить файл непридатним для відтворення.
Спосіб усунення проблеми
Щоб запобігти виникненню цієї проблеми в майбутніх музичних файлах FLAC, інсталюйте 25 травня 2021 р. – KB5003214 (збірки ОС 19041.1013, 19042.1013 і 19043.1013), підготовча версія.
Щоб відновити музичні файли FLAC, які зачіпають цю проблему, запустіть наведений нижче сценарій PowerShell.
Важливо
Цей сценарій не відновить втрачені метадані, що зберігалися у фреймі ID3. Однак, після чого файл знову можна відтворювати.
Відкрийте програму "Блокнот".
Скопіюйте та вставте в Блокнот такий сценарій:
# Авторське право 2021 Microsoft
# Цей сценарій відновить файл FLAC, який було пошкоджено Media Foundation щодо KB5003430.
# Для отримання додаткової інформації зверніться до KB5003430
param(
[parameter(Mandatory=$true,
HelpMessage="Шлях до файлу FLAC, який було пошкоджено Media Foundation",
ValueFromRemainingArguments=$true)]
[ValidateScript({ -not [String]::IsNullOrEmpty($_) -and (test-path $_) })]
[Рядок]$File
)
# Нам потрібно створити резервну копію поточного файлу на випадок, якщо у нас виникнуть помилки
$FileDirectory = Split-Path -Resolve $File
$Filename = Split-Path -leaf -resolve $File
$FullPath = Join-Path -Resolve $FileDirectory $Filename
$Filename = [String]::Format("Backup_{0:yyyyMMdd_hhmmss}_{1}", [DateTime]::Now, $Filename)
$BackupLocation = Join-Path $FileDirectory $Filename
Write-Output "Microsoft FLAC Repair Tool. Цей засіб відновить аудіофайл FLAC, пошкоджений під час редагування деталей."
Write-Output "Файл, якого це стосується: $FullPath"
Write-Output "Буде зроблено резервне копіювання файлу: $BackupLocation"
Write-Output «Ти хочеш продовжити?»
$choice=$host.ui.PromptForChoice("Виправлення сценарію FLAC", "Продовжити", ('&Так', '&Ні'), 1)
функція ParseStreamInfoMetadataBlock([System.IO.FileStream]$stream)
{
$blockType = $stream. ReadByte()
$lastBlock = ($blockType -shr 7) -ne 0
$blockType = $blockType -смуга 0x7F
if ($blockType -ne 0)
{
Повернення $false
}
$blockSize = (($stream. ReadByte() -shl 16) -bor ($stream. ReadByte() -shl 8) -bor $stream. ReadByte())
IF ($blockSize -lt 34)
{
Повернення $false
}
$minAudioBlockSize = ($stream. ReadByte() -shl 8) -bor $stream. ReadByte()
$maxAudioBlockSize = ($stream. ReadByte() -shl 8) -bor $stream. ReadByte()
ЯКЩО ($minAudioBlockSize -lt 16 -або $maxAudioBlockSize -lt 16)
{
Повернення $false
}
$minFrameSize = (($stream. ReadByte() -shl 16) -bor ($stream. ReadByte() -shl 8) -bor $stream. ReadByte())
$maxFrameSize = (($stream. ReadByte() -shl 16) -bor ($stream. ReadByte() -shl 8) -bor $stream. ReadByte())
$sampleInfo = (($stream. ReadByte() -shl 24) -bor ($stream. ReadByte() -shl 16) -bor ($stream. ReadByte() -shl 8) -bor $stream. ReadByte())
$sampleRate = $sampleInfo -shr 12
$channelCount = (($sampleInfo -shr 9) -смуга 0x7) + 1
$bitsPerSample = (($sampleInfo -shr 4) -смуга 0x1F) + 1
[UInt64]$sampleCount = (($stream. ReadByte() -shl 24) -bor ($stream. ReadByte() -shl 16) -bor ($stream. ReadByte() -shl 8) -bor $stream. ReadByte())
$sampleCount = ((([UInt64]$sampleInfo -band 0xF) -shl 32) -bor $sampleCount
$MD 5HashBytes = New-Object byte[] 16
$stream. Read($MD 5HashBytes, 0, $MD 5HashBytes.Length)
$MD 5Hash = [Guid]($MD 5HashBytes)
IF ($sampleRate -EQ 0)
{
Повернення $false
}
# Проходження цих перевірок означає, що ми, швидше за все, маємо заголовок потоку відомостей і можемо перебудувати файл
Write-Output "Відомості про файл Stream"
Write-Output "Частота дискретизації: $sampleRate"
Write-Output "Аудіоканали: $channelCount"
Write-Output "Глибина вибірки: $bitsPerSample"
Write-Output "MD5 Audio Sample Hash: $MD 5Hash"
Повернення $true
}
ЯКЩО ($choice -EQ 0)
{
Copy-Item $FullPath -призначення $BackupLocation -force
$stream = [System.IO.File]::Open($FullPath, [System.IO.FileMode]::Open)
$stream. Seek(4, [System.IO.SeekOrigin]::Begin)
У той час як ($stream. ReadByte() -eq 0) {}
# Тепер нам потрібно з'ясувати, де починається дійсний фрейм метаданих FLAC
# Швидше за все, ми вкажемо на останній байт елемента розміру, тому повернемо 4 байти назад і спробуємо ще раз
$flacDataStartPosition = $stream. Позиція - 4
$stream. Seek($flacDataStartPosition, [System.IO.SeekOrigin]::Begin)
while (-not(ParseStreamInfoMetadataBlock($stream)))
{
$flacDataStartPosition = $flacDataStartPosition + 1
$stream. Seek($flacDataStartPosition, [System.IO.SeekOrigin]::Begin)
}
# Вставте початковий код
$stream. Seek($flacDataStartPosition, [System.IO.SeekOrigin]::Begin)
if (Шлях до перевірки "$FullPath.tmp")
{
Remove-Item "$FullPath.tmp"
}
$fixedStream = [System.IO.File]::Open("$FullPath.tmp", [System.IO.FileMode]::CreateNew)
[byte[]]$startCode = [char[]]('f', 'L', 'a', 'C');
$fixedStream.Write($startCode, 0, $startCode.довжина)
$stream. CopyTo($fixedStream)
$stream. Close()
$fixedStream.Close()
Move-Item -Force "$FullPath.tmp" $FullPath
}У меню "Файл " виберіть команду "Зберегти".
У діалоговому вікні " Збереження документа" знайдіть папку, у якій потрібно зберегти сценарій PowerShell.
У полі "Ім'я файлу " введіть FixFlacFiles.ps1, змініть значення поля "Тип файлу " на "Текстові документи" (*.txt) і натисніть кнопку "Зберегти".
У Провіднику Windows знайдіть збережений сценарій PowerShell.
Клацніть сценарій правою кнопкою миші й виберіть команду "Запустити з PowerShell".
Коли з'явиться запит, введіть ім'я файлу FLAC, який неможливо відтворити, і натисніть клавішу Enter.