KB5003430:當 FLAC 編碼的音樂檔案在 Windows 檔案總管中編輯元資料時會損壞

Applies To
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

摘要

此更新解決了元資料編碼問題,該問題會導致 FLAC) 自由無損音訊編碼器 (音樂檔案若標題、藝人或其他元資料被更改,將無法播放。

原因

當 FLAC 檔案在 FLAC 標頭前包含 ID3 影格時,可能會發生此問題。 ID3 框架包含標題與藝術家等元資料。 FLAC 屬性處理器假設所有 FLAC 檔案起始於 4 位元組起始碼 fLaC,且未考慮檔案開頭的 ID3 幀。 因此,ID3 框架會被覆寫,而起始碼 fLaC 則使檔案無法播放。

解決方法

為避免未來 FLAC 音樂檔案出現此問題,請 於 2021 年 5 月 25 日安裝 KB5003214 (作業系統版本 19041.1013、19042.1013 及 19043.1013) 預覽版。

要修復受影響的 FLAC 音樂檔案,請執行以下 PowerShell 腳本。

重要

此腳本不會恢復 ID3 幀中遺失的元資料。 不過,這確實讓檔案可以重新播放。

  1. 開啟 [記事本]。

  2. 將以下腳本複製貼上到記事本:

    # 版權所有 2021 Microsoft
    # 此腳本將修復一個因媒體基金會而損壞的 FLAC 檔案,該檔案涉及KB5003430。
    # 詳情請參見KB5003430
    參數 (
    [參數 (強制=$true,
    HelpMessage=「Media Foundation 破壞的 FLAC 檔案路徑」,
    ValueFromRemainingArguments=$true) ]
    [ValidateScript ({ -not [String]::IsNullOrEmpty ($_) -and (Test-Path $_) }) ]
    [弦]$File
    )
    # 我們需要備份目前的檔案,以防有錯誤
    $FileDirectory = Split-Path -解決$File
    $Filename = Split-Path -葉子 -解決$File
    $FullPath = Join-Path -解決$FileDirectory $Filename
    $Filename = [字串]::格式 (“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)
    function ParseStreamInfoMetadataBlock ([System.IO.FileStream]$stream)
    {
    $blockType = $stream。ReadByte ()
    $lastBlock = ($blockType -shr 7) -ne 0
    $blockType = $blockType -頻段0x7F
    若 ($blockType -ne 0)
    {
    回歸$false
    }
    $blockSize = ( ($stream。ReadByte () -shl 16) -bor ($stream。ReadByte () -shl 8) -bor $stream。ReadByte () )
    如果 ($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 -頻段 0xF) -shl 32) -bor $sampleCount
    $MD 5HashBytes = New-Object 位元組[] 16
    $stream。讀取 ($MD 5HashBytes, 0, $MD 5HashBytes.長度)
    $MD 5Hash = [Guid] ($MD 5HashBytes)
    若 ($sampleRate -eq 0)
    {
    回歸$false
    }
    # 通過這些檢查代表我們很可能擁有串流資訊標頭,可以重建檔案
    Write-Output 「檔案Stream資訊」
    Write-Output 「取樣率:$sampleRate」
    Write-Output「音訊頻道:$channelCount」
    Write-Output 「樣本深度:$bitsPerSample」
    Write-Output 「MD5 音訊取樣雜湊:$MD 5雜湊」
    返回$true
    }
    若 ($choice -eq 0)
    {
    Copy-Item $FullPath -目的地$BackupLocation -原力
    $stream = [System.IO.File]::Open ($FullPath, [System.IO.FileMode]::Open)
    $stream。尋找 (4,[System.IO.SeekOrigin]::開始)
    而 ($stream。ReadByte () -eq 0) {}
    # 我們現在需要找出有效的 FLAC 元資料框架從哪裡開始
    # 我們很可能指向 size 成員的最後一個位元組,因此會回溯 4 位元組並重試
    $flacDataStartPosition = $stream。位置 - 4
    $stream。尋找 ($flacDataStartPosition,[System.IO.SeekOrigin]::開始)
    雖然 (-not (ParseStreamInfoMetadataBlock ($stream) ) )
    {
    $flacDataStartPosition = $flacDataStartPosition + 1
    $stream。尋找 ($flacDataStartPosition,[System.IO.SeekOrigin]::開始)
    }
    # 插入啟動代碼
    $stream。尋找 ($flacDataStartPosition,[System.IO.SeekOrigin]::開始)
    如果 (測試路徑「$FullPath.tmp」)
    {
    Remove-Item「$FullPath.tmp」
    }
    $fixedStream = [System.IO.File]::Open (“$FullPath.tmp”, [System.IO.FileMode]::CreateNew)
    [位元組[]]$startCode = [char[]] ('f', 'L', 'a', 'C') ;
    $fixedStream.寫入 ($startCode, 0, $startCode.長度)
    $stream。複製給 ($fixedStream)
    $stream。差點 ()
    $fixedStream。接近 ()
    Move-Item -原力「$FullPath.tmp」$FullPath
    }
  3. 按一下 [檔案] 功能表上的 [儲存]

  4. 「另存為」 對話框中,找到你想儲存 PowerShell 腳本的資料夾。

  5. 檔案名稱 框中,輸入 FixFlacFiles.ps1,將 另存為類型 框改為 文字文件 (*.txt) ,然後點 選儲存

  6. 在 Windows 檔案總管裡,找到你儲存的 PowerShell 腳本。

  7. 右鍵點這個腳本,然後點選 「用 PowerShell 執行」。

  8. 當提示時,輸入無法播放的 FLAC 檔案名稱,然後按下 Enter