Applies ToWindows 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 (OS 内部版本 19041.1013、19042.1013 和 19043.1013) 预览版

若要修复受影响的 FLAC 音乐文件,请运行以下 PowerShell 脚本。

重要: 此脚本不会还原 ID3 帧中存储的丢失元数据。 但是,它确实使文件再次可播放。

  1. 打开记事本。

  2. 将以下脚本复制并粘贴到记事本:

    # Copyright 2021 Microsoft

    # 此脚本将修复媒体基础在引用 KB5003430 时已损坏的 FLAC 文件。

    有关详细信息,请参阅 KB5003430

    param (

    [parameter (Mandatory=$true,

    HelpMessage="媒体基础已损坏的 FLAC 文件的路径",

    ValueFromRemainingArguments=$true) ]

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

    [String]$File

    )

    # 我们需要备份当前文件,避免出现任何错误

    $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 修复工具"。 此工具将修复在编辑其详细信息时已损坏的 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 -band 0x7F

    如果 ($blockType -ne 0)

    {

    返回$false

    }

    $blockSize = ( ($stream。ReadByte () -shl 16) - ($stream。ReadByte () -shl 8) -$stream。ReadByte () )

    如果 ($blockSize -lt 34)

    {

    返回$false

    }

    $minAudioBlockSize = ($stream。ReadByte () -shl 8) -$stream。ReadByte ()

    $maxAudioBlockSize = ($stream。ReadByte () -shl 8) -$stream。ReadByte ()

    如果 ($minAudioBlockSize -lt 16 -或 $maxAudioBlockSize -lt 16)

    {

    返回$false

    }

    $minFrameSize = ( ($stream。ReadByte () -shl 16) - ($stream。ReadByte () -shl 8) -$stream。ReadByte () )

    $maxFrameSize = ( ($stream。ReadByte () -shl 16) - ($stream。ReadByte () -shl 8) -$stream。ReadByte () )

    $sampleInfo = ( ($stream。ReadByte () -shl 24) - ($stream。ReadByte () -shl 16) - ($stream。ReadByte () -shl 8) -$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) - ($stream。ReadByte () -shl 16) - ($stream。ReadByte () -shl 8) -$stream。ReadByte () )

    $sampleCount = ( ([UInt64]$sampleInfo -band 0xF) -shl 32) -$sampleCount

    $MD 5HashBytes = New-Object byte[] 16

    $stream。读取 ($MD 5HashBytes、0、$MD 5HashBytes.Length)

    $MD 5Hash = [Guid] ($MD 5HashBytes)

    如果 ($sampleRate -eq 0)

    {

    返回$false

    }

    # 传递这些检查意味着我们有一个流信息标头,并且可以重新生成文件

    Write-Output"文件流信息"

    Write-Output"采样率:$sampleRate"

    Write-Output"音频通道:$channelCount"

    Write-Output"示例深度:$bitsPerSample"

    Write-Output"MD5 音频示例哈希:$MD 5Hash"

    返回$true

    }

    如果 ($choice -eq 0)

    {

    Copy-Item $FullPath -Destination $BackupLocation -Force

    $stream = [System.IO.File]::Open ($FullPath, [System.IO.FileMode]::Open)

    $stream。查找 (4,[System.IO.SeekOrigin]::Begin)

    同时 ($stream。ReadByte () -eq 0) {}

    # 现在,我们需要确定有效的 FLAC 元数据帧的开始位置

    #我们可能会指向大小成员的最后一个字节,因此我们将寻回 4 字节并重试

    $flacDataStartPosition = $stream。位置 - 4

    $stream。查找 ($flacDataStartPosition,[System.IO.SeekOrigin]::Begin)

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

    {

    $flacDataStartPosition = $flacDataStartPosition + 1

    $stream。查找 ($flacDataStartPosition,[System.IO.SeekOrigin]::Begin)

    }

    # 插入开始代码

    $stream。查找 ($flacDataStartPosition,[System.IO.SeekOrigin]::Begin)

    如果 (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。关闭 ()

    $fixedStream.Close ()

    Move-Item -Force "$FullPath.tmp" $FullPath

    }

  3. 在“文件”菜单上,单击“保存”。

  4. "另存 为"对话框中,找到要保存 PowerShell 脚本的文件夹。

  5. 在"文件名"框中,键入"FixFlacFiles.ps1",将"另存为类型"框更改为"文本文档" (*.txt) 然后单击"保存"。

  6. 在Windows资源管理器中,找到保存的 PowerShell 脚本。

  7. 右键单击脚本,并单击"使用 PowerShell 运行"。

  8. 系统提示时,键入不可播放 FLAC 文件的文件名,然后按Enter。

需要更多帮助?

需要更多选项?

了解订阅权益、浏览培训课程、了解如何保护设备等。

社区可帮助你提出和回答问题、提供反馈,并听取经验丰富专家的意见。