Tóm tắt
Bản cập nhật này khắc phục sự cố mã hóa siêu dữ liệu khiến các tệp nhạc Free Lossless Audio Codec (FLAC) không thể phát được nếu tiêu đề, nghệ sĩ hoặc siêu dữ liệu khác của chúng bị thay đổi.
Nguyên nhân
Sự cố này có thể xảy ra khi các tệp FLAC chứa khung ID3 trước tiêu đề FLAC. Khung ID3 chứa siêu dữ liệu như tiêu đề và nghệ sĩ. Trình xử lý thuộc tính FLAC giả định rằng tất cả các tệp FLAC đều bắt đầu với mã bắt đầu 4 byte fLaC và không tính đến khung ID3 ở đầu tệp. Do đó, khung ID3 sẽ bị ghi đè mà không có mã bắt đầu fLaC khiến cho tệp không thể phát được.
Giải pháp
Để ngăn chặn sự cố này đối với các tệp nhạc FLAC trong tương lai, hãy cài đặt Bản xem trước ngày 25 tháng 5 năm 2021—KB5003214 (Bản dựng HĐH 19041.1013, 19042.1013 và 19043.1013).
Để sửa các tệp nhạc FLAC bị ảnh hưởng, hãy chạy tập lệnh PowerShell sau.
Quan trọng
Tập lệnh này sẽ không khôi phục siêu dữ liệu bị mất đã được lưu trữ trong khung ID3. Tuy nhiên, tính năng này làm cho tệp có thể phát được trở lại.
Mở Notepad.
Sao chép và dán tập lệnh sau vào notepad:
# Bản quyền 2021 Microsoft
# Tập lệnh này sẽ sửa chữa tệp FLAC đã bị Media Foundation làm hỏng liên quan đến KB5003430.
# Tham khảo KB5003430 để biết thêm thông tin
param(
[tham số(Mandatory=$true,
HelpMessage="Đường dẫn đến tệp FLAC bị hỏng bởi Media Foundation",
ValueFromRemainingArguments=$true)]
[ValidateScript({ -not [Chuỗi]::IsNullOrEmpty($_) -and (Đường dẫn Thử nghiệm $_) })]
[Chuỗi]$File
)
# Chúng tôi cần sao lưu tệp hiện tại trong trường hợp chúng tôi gặp bất kỳ lỗi nào
$FileDirectory = Split-Path -Resolve $File
$Filename = Split-Path -Leaf -Resolve $File
$FullPath = Join-Path -Resolve $FileDirectory $Filename
$Filename = [Chuỗi]::Format("Backup_{0:yyyyMMdd_hhmmss}_{1}", [DateTime]::Now, $Filename)
$BackupLocation = Join-Path $FileDirectory $Filename
Write-Output "Công cụ sửa chữa Microsoft FLAC. Công cụ này sẽ sửa chữa tệp âm thanh FLAC bị hỏng khi chỉnh sửa chi tiết của tệp."
Write-Output "Tệp bị ảnh hưởng: $FullPath"
Write-Output "Bản sao lưu tệp sẽ được tạo: $BackupLocation"
Write-Output "Bạn có muốn tiếp tục không?"
$choice=$host.ui.PromptForChoice("Khắc phục tập lệnh FLAC", "Bạn có muốn tiếp tục không", ('&Có', "&Không'), 1)
hàm ParseStreamInfoMetadataBlock([System.IO.FileStream]$stream)
{
$blockType = $stream. ReadByte()
$lastBlock = ($blockType -shr 7) -ne 0
$blockType = $blockType -band 0x7F
IF ($blockType -ne 0)
{
$false trả lại
}
$blockSize = (($stream. ReadByte() -shl 16) -bor ($stream. ReadByte() -shl 8) -bor $stream. ReadByte())
IF ($blockSize -lt 34)
{
$false trả lại
}
$minAudioBlockSize = ($stream. ReadByte() -shl 8) -bor $stream. ReadByte()
$maxAudioBlockSize = ($stream. ReadByte() -shl 8) -bor $stream. ReadByte()
IF ($minAudioBlockSize -lt 16 -or $maxAudioBlockSize -lt 16)
{
$false trả lại
}
$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) -băng tần 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)
{
$false trả lại
}
# Vượt qua các kiểm tra này có nghĩa là chúng tôi có thể có tiêu đề thông tin luồng và có thể dựng lại tệp
Write-Output "Thông tin Stream tệp"
Write-Output "Sample Rate: $sampleRate" (Tốc độ lấy mẫu: )
Write-Output "Kênh Âm thanh: $channelCount"
Write-Output "Độ sâu mẫu: $bitsPerSample"
Write-Output "MD5 Audio Sample Hash: $MD 5Hash"
$true trả lại
}
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) {}
# Bây giờ chúng ta cần tìm ra khung siêu dữ liệu FLAC hợp lệ bắt đầu từ đâu
# Chúng tôi có thể đang trỏ tới byte cuối cùng của phần tử kích cỡ nên chúng tôi sẽ tìm kiếm lại 4 byte và thử lại
$flacDataStartPosition = $stream. Vị trí - 4
$stream. Seek($flacDataStartPosition, [System.IO.SeekOrigin]::Begin)
while (-not(ParseStreamInfoMetadataBlock($stream)))
{
$flacDataStartPosition = $flacDataStartPosition + 1
$stream. Seek($flacDataStartPosition, [System.IO.SeekOrigin]::Begin)
}
# Chèn mã bắt đầu
$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. Đóng ()
$fixedStream.Close()
Move-Item -Buộc $FullPath "$FullPath.tmp"
}Trên menu Tệp , bấm Lưu.
Trong hộp thoại Lưu Dưới dạng , xác định thư mục bạn muốn lưu tập lệnh PowerShell.
Trong hộp Tên tệp , nhập FixFlacFiles.ps1, thay đổi hộp Lưu dưới dạng thànhTài liệu Văn bản (*.txt) rồi bấm Lưu.
Trong Windows Explorer, xác định vị trí tập lệnh PowerShell bạn đã lưu.
Bấm chuột phải vào tập lệnh rồi bấm Chạy với PowerShell.
Khi được nhắc, hãy nhập tên tệp của tệp FLAC không thể phát rồi nhấn Enter.