如果你是音乐发烧友,应该知道Flac这种常见的无损音乐格式。Flac音乐文件支持元数据,用户可以编辑元数据,使音乐文件包含艺术家、专辑、曲目等信息。一般来说,元数据和音频数据没有关联,修改元数据不会影响音频本身。不过,近日微软官方宣布,Win10存在一个bug。在Win10中用资源管理器修改Flac文件的元数据会造成音频损坏!据WindowsLatest报道,微软发布的一份最新支持文档披露,在Win102004或之后的版本中,如果使用文件资源管理器修改Flac音乐文件的元数据,Flac音频文件将会丢失。这个bug出现在Win10专业版、家庭版、企业版、工作站版甚至其他版本的Win10中。根据微软本月早些时候发布的一份支持文件,Windows10的文件资源管理器通过破坏Flac文件头中包含的ID3帧或元数据而导致错误,该文件头负责存储音乐标题等音频注释。,artist,album,tracknumber等。在Win10上,Flac处理程序会忽略ID3帧。该程序认为Flac文件使用的是4字节文件头。Win10编辑Flac文件时,ID3帧被覆盖,导致没有起始码,导致音乐播放器无法识别修改后的文件。因此,在Win10中,如果直接使用文件资源管理器修改Flac音乐文件的标题、艺术家等元数据,将无法播放该文件。幸运的是,微软已经查明了该漏洞的根源,用户可以通过WindowsUpdate升级KB5003214补丁进行修复。在KB5003214补丁中,微软确认已修复上述错误。修改Flac的标题、艺术家等元数据后,Flac将不再变得无法播放。对于损坏的Flac文件,微软发布了一个PowerShell脚本来修复它们。运行脚本后,可以再次播放Flac文件,但ID3帧丢失的元数据信息无法恢复。下面介绍如何使用PowerShell脚本修复Flac文件。1.打开记事本;2.复制以下字符并粘贴到记事本中:#Copyright2021Microsoft #thisscriptWillRePairaflAcfileThathAsBeencorTedbyMediaFoundationInReferenceTokB5003430. #revERTOKB5003430FORFURTHERTHERINFORTHINFORMATION PARAM(parameter=paramiter=$true,$true,true, not[String]::IsNullOrEmpty($_)-and(Test-Path$_)})] [String]$File ) #Weneedtobackupthecurrentfileincasewehaveanyerrors $FileDirectory=Split-Path-Resolve$File $Filename=Split-Path-Leaf-Resolve$File $FullPath=Join-Path-Resolve$FileDirectory$Filename $Filename=[String]::Format("备份_{0:yyyyMMdd_hhmmss}_{1}",[DateTime]::Now,$Filename) $BackupLocation=Join-Path$FileDirectory$Filename Write-Output"MicrosoftFLACRepairTool.ThistoolwillrepairiraFLAaudiofilethatwascorruptedwheneditingitsdetails."putWrite-Output“受影响的文件:$FullPath” Write-Output"Abackupofthefilewillbemade:$BackupLocation" Write-Output"Doyouwishtocontinue?" $choice=$host.ui.PromptForChoice("FixingFLACScript","Doyouwishtocontinue",('&Yes','&No'),1) functionParseStreamInfoMetadataBlock([System.IO.FileStream]$stream) { $blockType=$stream.ReadByte() $lastBlock=($blockType-shr7)-ne0 $blockType=$blockType-band0x7F if($blockType-ne0) { return$false } $blockSize=(($stream.ReadByte()-shl16)-bor($stream.ReadByte()-shl8)-bor$stream.ReadByte()) if($blockSize-lt34) { return$false } $minAudioBlockSize=($stream.ReadByte()-shl8)-bor$stream.ReadByte() $maxAudioBlockSize=($stream.ReadByte()-shl8)-bor$stream.ReadByte() if($minAudioBlockSize-lt16-or$maxAudioBlockSize-lt16) { return$false } $minFrameSize=(($stream.ReadByte()-shl16)-bor($stream.ReadByte()-shl8)-bor$stream.ReadByte()) $maxFrameSize=(($stream.ReadByte()-shl16)-bor($stream.ReadByte()-shl8)-bor$stream.ReadByte()) $sampleInfo=(($stream.ReadByte()-shl24)-bor($stream.ReadByte()-shl16)-bor($stream.ReadByte()-shl8)-bor$stream.ReadByte()) $sampleRate=$sampleInfo-shr12 $channelCount=(($sampleInfo-shr9)-band0x7)+1 $bitsPerSample=(($sampleInfo-shr4)-band0x1F)+1 [UInt64]$sampleCount=(($stream.ReadByte()-shl24)-bor($stream.ReadByte()-shl16)-bor($stream.ReadByte()-shl8)-bor$stream.ReadByte()) $sampleCount=(([UInt64]$sampleInfo-band0xF)-shl32)-bor$sampleCount $MD5HashBytes=New-Objectbyte[]16 $stream.Read($MD5HashBytes,0,$MD5HashBytes.Length) $MD5Hash=[Guid]($MD5HashBytes) if($sampleRate-eq0) { return$false } #Passingthesechecksmeansthatwelikelyhaveastreaminfoheaderandcanrebuildthefile Write-Output"FileStreamInformation" WriteRateOutput:"$sampleRate-Output:" 写输出“AudioChannels:$channelCount” 写输出"SampleDepth:$bitsPerSample" 写输出"MD5AudioSampleHash:$MD5Hash" return$true } if($choice-eq0) { 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()-eq0){} #WenowneedtofigureoutwhereavalidFLACmetadataframebegins #Wearelikelypointingtothelastbyteofthesizememberssowe'llseekback4bytesandretrystream $flac=DataStartPosition-4 $stream.Seek($flacDataStartPosition,[System.IO.SeekOrigin]::Begin) while(-not(ParseStreamInfoMetadataBlock($stream))) { $flacDataStartPosition=$flacDataStartPosition+1 $stream.Seek($flacDataStartPosition,[System.IO.SeekOrigin]::Begin) } #Insertthestartcode $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”,将保存的文件类型改为TextDocuments(*.txt);5.输入保存PowerShell脚本的目录;6、右击刚才保存的脚本,选择“使用PowerShell运行”;7.出现提示时,输入无法播放的Flac文件的文件名,然后按Enter。微软建议您安装本月推送的可选累积更新,以避免修改Flac文件元数据时出现问题。
