Windows 10 BUG會破壞FLAC音頻文件 現已修復

如果你習慣從在線商城下載 FLAC(自由無損音頻壓縮編碼)格式的音頻文件,請不要使用 Windows 10 系統的資源管理器來編輯元數據。在 Windows 10 Version 2004 及更高版本中存在一個錯誤,如果使用資源管理器修改元數據,就有可能會損壞 FLAC 音頻文件。

QQ截圖20210602100734.jpg

這個 BUG 影響 Windows 10 專業版、家庭版、企業版、工作站和其他 SKU 版本。根據本月早些時候發布的支持文件,Windows 10的文件資源管理器的錯誤將破壞某些FLAC文件,這些文件在FLAC頭之前包含一個ID3框架。ID3是一個框架,它負責存儲信息,如音樂標題、藝術家、專輯、曲目編號等。

在 Windows 10 系統,FLAC處理程序忽略了ID3框架,因為它認為FLAC文件在開頭使用4字節的fLaC。當音樂文件被用戶編輯時,ID3 框架被覆蓋了,沒有開始代碼。因此,音樂播放器無法識別修改後的文件。如果音樂文件的標題、藝術家或其他元數據在文件資源管理器中被改變,音樂文件就不會播放或加載。

幸運的是,微軟已經確定了根本原因,現在可以通過Windows Update進行修復。在 KB5003214 更新的更新日誌中,微軟確認該錯誤已被修復,如果你改變了他們的標題、藝術家或其他元數據,自由無損音頻編解碼器(FLAC)音樂文件將不再變得無法播放。

對於那些有損壞的音樂文件,微軟已經發布了一個新的PowerShell腳本,你可以運行它來使文件再次播放。然而,它不能恢復存儲在ID3框架中的丟失的元數據。為了避免FLAC音樂文件在未來出現問題,微軟建議應用本月的可選累積更新。

解決方案

1. 打開記事本

2. 將以下腳本代碼複製到記事本中

# Copyright 2021 Microsoft

# This script will repair a FLAC file that has been corrupted by Media Foundation in reference to KB5003430.

# Refer to KB5003430 for further information

param(

[parameter(Mandatory =$ true,

HelpMessage = “The path to the FLAC file that has been corrupted by Media Foundation”,

ValueFromRemainingArguments =$ true)]

[ValidateScript({ -not [String]::IsNullOrEmpty( $_) -and (Test-Path $_) })]

[String] $ File

)

# We need to back up the current file incase we have any errors

$ 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. This tool will repair a FLAC audio file that was corrupted when editing its details.”

Write-Output “Affected File: $ FullPath”

Write-Output “A backup of the file will be made: $ BackupLocation”

Write-Output “Do you wish to continue?”

$ choice =$ host.ui.PromptForChoice(“Fixing FLAC Script”, “Do you wish to continue”, (‘&Yes’, ‘&No’), 1)

function ParseStreamInfoMetADATABlock([System.IO.FileStream] $ stream)

{

$ blockType = $ stream.ReadByte()

$ lastBlock = ($ blockType -shr 7) -ne 0

$ blockType = $ blockType -band 0x7F

if ($ blockType -ne 0)

{

return $ false

}

$ blockSize = (($ stream.ReadByte() -shl 16) -bor ($ stream.ReadByte() -shl 8) -bor $ stream.ReadByte())

if ($ blockSize -lt 34)

{

return $ 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)

{

return $ 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

$ MD5HashBytes = New-Object byte[] 16

$ stream.Read( $ MD5HashBytes, 0, $ MD5HashBytes.Length)

$ MD5Hash = [Guid]( $ MD5HashBytes)

if ($ sampleRate -eq 0)

{

return $ false

}

# Passing these checks means that we likely have a stream info header and can rebuild the file

Write-Output “File Stream Information”

Write-Output “Sample Rate: $ sampleRate”

Write-Output “Audio Channels: $ channelCount”

Write-Output “Sample Depth: $ bitsPerSample”

Write-Output “MD5 Audio Sample Hash: $ MD5Hash”

return $ 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)

while ($ stream.ReadByte() -eq 0) {}

# We now need to figure out where a valid FLAC metadata frame begins

# We are likely pointing to the last byte of the size member so we’ll seek back 4 bytes and retry

$ flacDataStartPosition = $ stream.Position – 4

$ stream.Seek( $ flacDataStartPosition, [System.IO.SeekOrigin]::Begin)

while (-not(ParseStreamInfoMetadataBlock( $ stream)))

{

$ flacDataStartPosition = $ flacDataStartPosition + 1

$ stream.Seek( $ flacDataStartPosition, [System.IO.SeekOrigin]::Begin)

}

# Insert the start code

$ stream.Seek( $ flacDataStartPosition, [System.IO.SeekOrigin]::Begin)

if (Test-Path “$ 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文件的文件名,然後按回車鍵。

(0)
上一篇 2021-06-02 11:11
下一篇 2021-06-02 11:11

相关推荐