title
Products            Buy            Support Forum            Professional            About            Codec Central
 

Microsoft releases FLAC file corruption issue fix today

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • rfs12307

    • Feb 2021
    • 1

    Microsoft releases FLAC file corruption issue fix today

    Summary
    This update addresses a metadata encoding issue which causes Free Lossless Audio Codec (FLAC) music files to become unplayable if their title, artist, or other metadata is changed.

    Cause
    This issue might occur when the FLAC files contain an ID3 frame before the FLAC header. The ID3 frame contains metadata such as title and artist. The FLAC property handler assumed that all FLAC files started with the 4 byte start code fLaC and did not take into account the ID3 frame at the beginning of the file. Therefore, the ID3 frame would be overwritten without the start code fLaC rendering the file unplayable.

    Resolution
    To prevent this issue for future FLAC music files, install May 25, 2021—KB5003214 (OS Builds 19041.1013, 19042.1013, and 19043.1013) Preview.
    To repair affected FLAC music files, run the following PowerShell script:

    Important: This script will not restore the lost metadata that was stored in the ID3 frame. However, it does make the file playable again.


    Open Notepad.

    Copy-and-paste the following script into notepad:

    * 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

    }

    On the File menu, click Save.

    In the Save As dialog box, locate the folder in which you want to save the PowerShell script.

    In the File name box, type FixFlacFiles.ps1, change the Save as type box to Text Documents (*.txt) and then click Save.

    In Windows Explorer, locate the PowerShell script you saved.

    Right-click the script and then click Run with PowerShell.

    When prompted, type in the file name of the unplayable FLAC file and then press Enter.
  • Spoon
    Administrator
    • Apr 2002
    • 44574

    #2
    Re: Microsoft releases FLAC file corruption issue fix today

    Another good reason to not let MS anywhere near your audio tracks:

    Windows 10 comes with the ability to read ID Tags for a bunch of standard codecs such as: mp3, wave, flac, m4a, opus, ogg The issue can be, that Microsoft do not support the full range of ID Tags that dBpoweramp does, such as Wave ID3 chunk, or the full subset of id3v2.4 tags. Even worse for opus and ogg Microsoft do not read


    We have never corrupted flac files in the last 20 years...
    Spoon
    www.dbpoweramp.com

    Comment

    • kwm1800

      • Jul 2014
      • 6

      #3
      Re: Microsoft releases FLAC file corruption issue fix today

      So... this only happens when you use windows explorer to edit the tags, right?

      I did not even know the explorer could do that.

      Comment

      • Spoon
        Administrator
        • Apr 2002
        • 44574

        #4
        Re: Microsoft releases FLAC file corruption issue fix today

        Correct
        Spoon
        www.dbpoweramp.com

        Comment

        • Neid

          • Apr 2021
          • 4

          #5
          Re: Microsoft releases FLAC file corruption issue fix today

          --deleted--
          Last edited by Neid; May 31, 2021, 05:31 PM. Reason: wanted to delete post

          Comment

          Working...

          ]]>