[PConline 資訊]如果你是一名音樂發燒友,那麼應該知道Flac這種常見的無損音樂格式。Flac音樂檔案支援metadata,使用者可以編輯metadata,讓音樂檔案帶有藝術家、所屬專輯、
2021-06-06 03:00:33
[PConline 資訊]如果你是一名音樂發燒友,那麼應該知道Flac這種常見的無損音樂格式。Flac音樂檔案支援metadata,使用者可以編輯metadata,讓音樂檔案帶有藝術家、所屬專輯、音軌等等資訊。通常來說,metadata和音訊資料並不相關,修改metadata並不會影響音訊本身。但是,近日微軟官方公佈了Win10中存在一個Bug,在Win10中用資源管理器修改Flac檔案的metadata,竟會導致音訊的損壞!
根據Windows Latest的報道,微軟最新發布的一份支援檔案披露,如果在Win10的2004或者更高版本中,使用檔案資源管理器修改Flac音樂檔案的metadata,就會損耗Flac音訊檔案。這個Bug在Win10專業版、家庭版、企業版、工作站版乃至其他版本的Win10中均有出現。
根據微軟本月早些時候釋出的支援檔案,Win10的檔案資源管理器導致了這個錯誤,它破壞了Flac檔案頭包含的ID3框架也就是metadata,而這個ID3框架負責儲存音訊的註釋,例如音樂標題、藝術家、專輯、曲目編號等。在Win10上,Flac的處理程式忽視了ID3框架,該程式認為Flac檔案在使用4位元組的檔案頭,當Flac檔案被Win10編輯的時候,ID3框架被覆蓋了,導致沒有了開始程式碼,導致了音樂播放器無法識別被修改後的檔案。
因此,在Win10中,如果你直接用檔案資源管理器修改Flac音樂檔案的標題、藝術家等metadata,會導致該檔案無法播放。
幸運的是,微軟已經確定了Bug的根本原因,使用者可以通過Windows Update升級KB5003214補丁進行修復。
在KB5003214補丁中,微軟確認了上文提到的錯誤已經被修復,修改了Flac的標題、藝術家等metadata後,Flac不會再變得無法播放。而對於已經損壞了的Flac檔案,微軟則釋出了一個PowerShell指令碼來進行修復,運行該指令碼後Flac檔案即可重新播放,不過已經從ID3框架中丟失了的metadata資訊並不能恢復。
下面是利用PowerShell指令碼修復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、儲存檔案,在「另存為」對話方塊中,將目錄定位到你想要儲存PowerShell指令碼的位置;
4、在檔名輸入框中,輸入「FixFlacFiles.ps1」,將另存為檔案的類型更改為Text Documents (*.txt);
5、進入到你儲存該PowerShell指令碼的目錄;
6、右鍵點選剛剛儲存的指令碼,然後選擇「使用PowerShell運行」;
7、出現提示時,輸入無法播放的Flac檔案的檔名,然後按下回車鍵。
微軟建議大家安裝本月推送的可選累積更新,以避免修改Flac檔案metadata出現的問題。
相關文章
[PConline 資訊]如果你是一名音樂發燒友,那麼應該知道Flac這種常見的無損音樂格式。Flac音樂檔案支援metadata,使用者可以編輯metadata,讓音樂檔案帶有藝術家、所屬專輯、
2021-06-06 03:00:33
就在大家都以為4G已成為過氣技術的時候,華為卻悄悄釋出了4款4G手機,支援4G的發展,這或許預示著4G將煥發青春,給4G的發展提供動力。華為是5G的旗手,它的5G專利位居全球第一,在去年
2021-06-05 23:56:51
IT之家 6 月 5 日訊息 AMD 目前的銳龍 5000、5000G 系列處理器採用的是 Zen 3 架構核心,臺積電 7nm 工藝製造。據外媒 VideoCardz 訊息,一位知名 YouTuber @Gamers Nexus 近日
2021-06-05 23:54:06
要說這段時間科技圈最熱的事件,莫過於華為自研鴻蒙OS系統的釋出了,已經有很多小夥伴收到了鴻蒙OS的推送,華為mate40系列成為了首批適配機型,就數碼博主測試來看,鴻蒙系統的穩定性
2021-06-05 23:34:42
目前,一場史詩級別的缺芯危機正在全球半導體行業上演,而造成多領域晶片短缺的主要因素,無疑是晶片代廠商產能緊張。因此,為了緩解晶片供應緊張、應對市場的強勁需求,臺積電、三星
2021-06-05 23:32:17
這幾天去線下實體店看了一下手機,尋思著給父母換一臺手機,原本打算去看看華為nova8的,去之前就已經做好心理準備了,只要店裡基礎版本有現貨,那麼就打算直接買了,也算是為支援國產
2021-06-05 23:12:43