KB5003430: FLAC кодираният музикален файл е повреден, когато метаданните се редактират в Windows Explorer

Отнася се за
Windows 10 Enterprise, version 2004 Windows 10 Home and Pro, version 2004 Windows 10 Pro, version 2004 Windows 10 Enterprise and Education, version 2004 Windows 10 Pro Education, version 2004 Windows 10 Pro for Workstations, version 2004 Windows 10 Pro, version 20H2 Windows 10 Enterprise, version 20H2 Windows 10 Enterprise and Education, version 20H2 Windows 10 Home and Pro, version 20H2 Windows 10 Pro Education, version 20H2 Windows 10 Pro for Workstations, version 20H2

Обобщение

Тази актуализация обръща внимание на проблем с кодиране на метаданни, при който музикалните файлове на 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 рамката. Това обаче прави файла отново играем.

  1. Отворете Notepad.

  2. Копирайте и поставете следния скрипт в Notepad:

    # Copyright 2021 Microsoft
    # Този скрипт ще поправи FLAC файл, който е повреден от Media Foundation във връзка с KB5003430.
    # Вижте KB5003430 за повече информация
    param(
    [parameter(Mandatory=$true,
    HelpMessage="Пътят до файла FLAC, който е повреден от Media Foundation",
    ValueFromRemainingArguments=$true)]
    [ValidateScript({ -not [String]::IsNullOrEmpty($_) -and (Test-Path $_) })]
    [String]$File
    )
    # Трябва да архивираме текущия файл, в случай че имаме грешки
    $FileDirectory = Split-Path -Разрешаване на $File
    $Filename = Split-Path -leaf -resolve $File
    $FullPath = Join-Path -Разрешаване на $FileDirectory $Filename
    $Filename = [String]::Format("Backup_{0:yyyyMMdd_hhmmss}_{1}", [DateTime]::Now, $Filename)
    $BackupLocation = Join-Path $FileDirectory $Filename
    Write-Output "Инструмент за поправка на Microsoft FLAC. Този инструмент ще поправи 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 -band 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()
    if ($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) -band 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 "Sample Rate: $sampleRate"
    Write-Output "Аудио канали: $channelCount"
    Write-Output "Дълбочина на извадката: $bitsPerSample"
    Write-Output "MD5 аудио sample hash: $MD 5Hash"
    връщане на $true
    }
    if ($choice -eq 0)
    {
    Copy-Item $FullPath -Destination $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.Length)
    $stream. CopyTo($fixedStream)
    $stream. Close()
    $fixedStream.Close()
    Move-Item – Force "$FullPath.tmp" $FullPath
    }
  3. В менюто "Файл" щракнете върху "Запиши".

  4. В диалоговия прозорец "Запиши като " намерете папката, в която искате да запишете скрипта на PowerShell.

  5. В полето за име на файл въведете FixFlacFiles.ps1, променете полето "Запиши като тип" на "Текстови документи" (*.txt) и след това щракнете върху "Запиши".

  6. В Windows Explorer намерете скрипта на PowerShell, който записахте.

  7. Щракнете с десния бутон върху скрипта и след това щракнете върху "Изпълнение с PowerShell".

  8. Когато получите подкана, въведете името на файла на FLAC файла, който не може да се възпроизвежда, и след това натиснете Enter.