KB5003430: Hudební soubor kódovaný ve formátu FLAC je při úpravě metadat v Průzkumníku Windows poškozen

Platí pro
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

Souhrn

Tato aktualizace řeší problém s kódováním metadat, který způsobuje, že hudební soubory ve formátu FLC (Free Lossless Audio Codec) nejdou přehrát, pokud se změní jejich název, interpret nebo jiná metadata.

Příčina

K tomuto problému může dojít, pokud soubory FLAC obsahují před hlavičkou FLAC rámec ID3. Rámec ID3 obsahuje metadata, jako je název a interpret. Obslužná rutina vlastností FLAC předpokládala, že všechny soubory FLAC začínaly se 4bajtovým startovacím kódem fLaC a nebraly v úvahu rámec ID3 na začátku souboru. Proto by byl ID3 rámec přepsán bez startovacího kódu fLaC, čímž by se soubor stal nepřehratelným.

Řešení

Pokud chcete tomuto problému zabránit u budoucích hudebních souborů FLAC, nainstalujte si verzi Preview z 25. května 2021 – KB5003214 (buildy operačního systému 19041.1013, 19042.1013 a 19043.1013).

Pokud chcete opravit ovlivněné hudební soubory FLAC, spusťte následující skript PowerShellu.

Důležité

Tento skript neobnoví ztracená metadata, která byla uložena v rámci ID3. Soubor však bude možné znovu přehrát.

  1. Otevřete Poznámkový blok.

  2. Zkopírujte a vložte následující skript do Poznámkového bloku:

    # Autorská práva 2021 Microsoft
    # Tento skript opraví soubor FLAC, který byl poškozen společností Media Foundation v souvislosti s KB5003430.
    # Další informace najdete v KB5003430
    param(
    [parameter(Mandatory=$true,
    HelpMessage="Cesta k souboru FLAC, který byl poškozen Media Foundation",
    ValueFromRemainingArguments=$true)]
    [ValidateScript({ -not [String]::IsNullOrEmpty($_) -and (Test-Path $_) })]
    [Řetězec]$File
    )
    # Musíme zálohovat aktuální soubor pro případ, že bychom měli nějaké chyby
    $FileDirectory = Split-Path -Resolve $File
    $Filename = Split-Path -list -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 "Nástroj pro opravu Microsoft FLAC. Tento nástroj opraví zvukový soubor FLAC, který byl poškozen při úpravě jeho podrobností."
    Write-Output "Ovlivněný soubor: $FullPath"
    Write-Output "Bude vytvořena záloha souboru: $BackupLocation"
    Write-Output Chcete pokračovat?
    $choice=$host.ui.PromptForChoice("Oprava skriptu FLAC", "Chcete pokračovat", ('&Ano', '&Ne'), 1)
    function ParseStreamInfoMetadataBlock([System.IO.FileStream]$stream)
    {
    $blockType = $stream. ReadByte()
    $lastBlock = ($blockType -shr 7) -ne 0
    $blockType = $blockType pásmová 0x7F
    if ($blockType -ne 0)
    {
    Vrátit $false
    }
    $blockSize = (($stream. ReadByte() -shl 16) -bor ($stream. ReadByte() -shl 8) -bor $stream. ReadByte())
    if ($blockSize -lt 34)
    {
    Vrátit $false
    }
    $minAudioBlockSize = ($stream. ReadByte() -shl 8) -bor $stream. ReadByte()
    $maxAudioBlockSize = ($stream. ReadByte() -shl 8) -bor $stream. ReadByte()
    if ($minAudioBlockSize -lt 16 -or $maxAudioBlockSize -lt 16)
    {
    Vrátit $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) -band 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)
    {
    Vrátit $false
    }
    # Úspěšné absolvování těchto kontrol znamená, že pravděpodobně máme hlavičku s informacemi o streamu a můžeme soubor znovu sestavit
    Write-Output "Informace o Stream souboru"
    Write-Output "Vzorkovací frekvence: $sampleRate"
    Write-Output "Audio kanály: $channelCount"
    Write-Output "Hloubka vzorku: $bitsPerSample"
    Write-Output "Hodnota hash ukázky zvuku MD5: $MD 5Hash"
    Vrátit $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)
    zatímco ($stream. ReadByte() -eq 0) {}
    # Nyní musíme zjistit, kde začíná platný rámec metadat FLAC
    # Pravděpodobně ukazujeme na poslední bajt členu size, takže se vrátíme o 4 bajty zpět a zkusíme to znovu
    $flacDataStartPosition = $stream. Pozice - 4
    $stream. Seek($flacDataStartPosition, [System.IO.SeekOrigin]::Begin)
    while (-not(ParseStreamInfoMetadataBlock($stream)))
    {
    $flacDataStartPosition = $flacDataStartPosition + 1
    $stream. Seek($flacDataStartPosition, [System.IO.SeekOrigin]::Begin)
    }
    # Vložte startovní kód
    $stream. Seek($flacDataStartPosition, [System.IO.SeekOrigin]::Begin)
    KDYŽ (testovací cesta "$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. Kopírovat do ($fixedStream)
    $stream. Close()
    $fixedStream.Close()
    Move-Item – Vynutit $FullPath "$FullPath.tmp"
    }
  3. V nabídce Soubor klikněte na příkaz Uložit.

  4. V dialogovém okně Uložit jako vyhledejte složku, do které chcete uložit skript PowerShellu.

  5. Do pole Název souboru zadejte FixFlacFiles.ps1, změňte pole Uložit jako typ na Textové dokumenty (*.txt) a klikněte na Uložit.

  6. V Průzkumníkovi Windows vyhledejte uložený skript PowerShellu.

  7. Klikněte pravým tlačítkem myši na skript a pak klikněte na Spustit s PowerShellem.

  8. Po zobrazení výzvy zadejte název nepřehratelného souboru FLAC a stiskněte klávesu Enter.