KB5003430: El archivo de música codificado FLAC se daña cuando los metadatos se editan en el Explorador de Windows

Se aplica a
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

Resumen

Esta actualización soluciona un problema de codificación de metadatos que hace que los archivos de música Free Lossless Audio Codec (FLAC) no se puedan reproducir si se cambia el título, el artista u otros metadatos.

Causa

Este problema puede producirse cuando los archivos FLAC contienen un marco ID3 antes del encabezado FLAC. El marco ID3 contiene metadatos como el título y el artista. El controlador de propiedades FLAC asumió que todos los archivos FLAC comenzaron con el código de inicio de 4 bytes fLaC y no tuvieron en cuenta el marco ID3 al comienzo del archivo. Por lo tanto, el marco ID3 se sobrescribiría sin el código de inicio fLaC, lo que haría que el archivo no se pueda reproducir.

Resolución

Para evitar este problema en futuros archivos de música FLAC, instale el 25 de mayo de 2021: versión preliminar de KB5003214 (compilaciones del SO 19041.1013, 19042.1013 y 19043.1013).

Para reparar los archivos de música FLAC afectados, ejecute el siguiente script de PowerShell.

Importante

Este script no restaurará los metadatos perdidos que se almacenaron en el marco ID3. Sin embargo, hace que el archivo se pueda reproducir de nuevo.

  1. Abra el Bloc de notas.

  2. Copie y pegue el siguiente script en el Bloc de notas:

    # Derechos de autor 2021 Microsoft
    # Este script reparará un archivo FLAC que ha sido dañado por Media Foundation en referencia a KB5003430.
    # Consulte KB5003430 para obtener más información
    param(
    [parameter(Mandatory=$true,
    HelpMessage="The path to the FLAC file that has been damaged by Media Foundation",
    ValueFromRemainingArguments=$true)]
    [ValidateScript({ -not [String]::IsNullOrEmpty($_) -and (Test-Path $_) })]
    [cadena]$File
    )
    # Necesitamos hacer una copia de seguridad del archivo actual en caso de que tengamos algún error
    $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 "Herramienta de reparación Microsoft FLAC. Esta herramienta reparará un archivo de audio FLAC que se corrompió al editar sus detalles".
    Write-Output "Archivo afectado: $FullPath"
    Write-Output "Se realizará una copia de seguridad del archivo: $BackupLocation"
    Write-Output "¿Desea continuar?"
    $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
    $MD 5HashBytes = New-Object byte[] 16
    $stream. Read($MD 5HashBytes, 0, $MD 5HashBytes.Length)
    $MD 5Hash = [Guid]($MD 5HashBytes)
    if ($sampleRate -eq 0)
    {
    return $false
    }
    # Pasar estas comprobaciones significa que es probable que tengamos un encabezado de información de flujo y podamos reconstruir el archivo
    Write-Output "Información de Stream de archivos"
    Write-Output "Velocidad de muestra: $sampleRate"
    Write-Output "Canales de audio: $channelCount"
    Write-Output "Profundidad de muestra: $bitsPerSample"
    Write-Output "Hash de muestra de audio MD5: $MD 5Hash"
    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) {}
    # Ahora tenemos que averiguar dónde comienza un marco de metadatos FLAC válido
    # Es probable que estemos apuntando al último byte del miembro de tamaño, por lo que buscaremos 4 bytes y volveremos a intentarlo
    $flacDataStartPosition = $stream. Posición - 4
    $stream. Seek($flacDataStartPosition, [System.IO.SeekOrigin]::Begin)
    while (-not(ParseStreamInfoMetadataBlock($stream)))
    {
    $flacDataStartPosition = $flacDataStartPosition + 1
    $stream. Seek($flacDataStartPosition, [System.IO.SeekOrigin]::Begin)
    }
    # Insertar el código de inicio
    $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. Copiar a($fixedStream)
    $stream. Close()
    $fixedStream.close()
    Move-Item -Force "$FullPath.tmp" $FullPath
    }
  3. En el menú Archivo, haga clic en Guardar.

  4. En el cuadro de diálogo Guardar como , busque la carpeta en la que desea guardar el script de PowerShell.

  5. En el cuadro Nombre de archivo , escriba FixFlacFiles.ps1, cambie el cuadro Guardar como tipoa Documentos de texto (*.txt) y, a continuación, haga clic en Guardar.

  6. En el Explorador de Windows, busque el script de PowerShell que guardó.

  7. Haga clic con el botón derecho en el script y luego haga clic en Ejecutar con PowerShell.

  8. Cuando se le solicite, escriba el nombre del archivo FLAC que no se puede reproducir y presione Entrar.