You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows环境下提取WAV文件末尾嵌入XML元数据的方法求助

解决WAV文件末尾XML元数据批量提取并生成Excel列表的问题

修正后的PowerShell脚本

$directory = "C:\test"
$outputCsv = "C:\test\call_metadata.csv"
$results = @()

# 定义XML起始和结束标记的字节序列
$startTagBytes = [System.Text.Encoding]::UTF8.GetBytes("<recording>")
$endTagBytes = [System.Text.Encoding]::UTF8.GetBytes("</recording>")

$wavFiles = Get-ChildItem -Path $directory -Filter *.wav

foreach ($file in $wavFiles) {
    Write-Host "Processing file: $($file.Name)"
    $fileBytes = [System.IO.File]::ReadAllBytes($file.FullName)
    
    # 从文件末尾逆向查找结束标记
    $endIndex = -1
    for ($i = $fileBytes.Length - $endTagBytes.Length; $i -ge 0; $i--) {
        $match = $true
        for ($j = 0; $j -lt $endTagBytes.Length; $j++) {
            if ($fileBytes[$i + $j] -ne $endTagBytes[$j]) {
                $match = $false
                break
            }
        }
        if ($match) {
            $endIndex = $i + $endTagBytes.Length
            break
        }
    }
    
    if ($endIndex -eq -1) {
        Write-Host "No </recording> tag found in $($file.Name)"
        $results += [PSCustomObject]@{
            Filename = $file.Name
            Status = "XML not found"
        }
        continue
    }
    
    # 从结束标记位置逆向查找起始标记
    $startIndex = -1
    for ($i = $endIndex - $startTagBytes.Length; $i -ge 0; $i--) {
        $match = $true
        for ($j = 0; $j -lt $startTagBytes.Length; $j++) {
            if ($fileBytes[$i + $j] -ne $startTagBytes[$j]) {
                $match = $false
                break
            }
        }
        if ($match) {
            $startIndex = $i
            break
        }
    }
    
    if ($startIndex -eq -1) {
        Write-Host "No <recording> tag found in $($file.Name)"
        $results += [PSCustomObject]@{
            Filename = $file.Name
            Status = "XML start tag missing"
        }
        continue
    }
    
    # 提取XML字节并转换为UTF8字符串
    $xmlBytes = $fileBytes[$startIndex..($endIndex - 1)]
    $xmlContent = [System.Text.Encoding]::UTF8.GetString($xmlBytes)
    
    try {
        # 解析XML节点
        $xml = [xml]$xmlContent
        $recordingNode = $xml.SelectSingleNode("//recording")
        
        # 按实际XML结构提取元数据,自行调整字段
        $metadata = [PSCustomObject]@{
            Filename = $file.Name
            CallID = $recordingNode.callID
            FromNumber = $recordingNode.fromNumber
            ToNumber = $recordingNode.toNumber
            StartTime = $recordingNode.startTime
            Duration = $recordingNode.duration
            # 新增其他需要的字段
        }
        
        $results += $metadata
        Write-Host "Successfully extracted metadata from $($file.Name)"
    }
    catch {
        Write-Host "Failed to parse XML in $($file.Name): $_"
        $results += [PSCustomObject]@{
            Filename = $file.Name
            Status = "XML parse error: $_"
        }
    }
}

# 导出为CSV(Excel可直接打开)
$results | Export-Csv -Path $outputCsv -NoTypeInformation -Encoding UTF8
Write-Host "Done! Metadata exported to $outputCsv"

原代码失败原因

  1. 二进制转码乱码:WAV音频部分是二进制数据,直接转UTF8字符串会产生大量无效字符,破坏XML标签结构,导致正则无法匹配。
  2. 正则匹配限制:原正则使用.+?,默认不匹配换行符,若XML包含换行则匹配失败。
  3. 低效全量读取:读取整个大文件的二进制内容转成字符串,完全没必要处理音频部分,浪费资源。

解决方案核心要点

  • 逆向字节匹配:从文件末尾查找</recording>标记,再向前定位<recording>,只提取XML部分的字节,避开音频二进制数据。
  • 字节级精准匹配:直接操作文件字节,避免编码转换带来的乱码问题,确保标记匹配准确。
  • 容错处理:添加try-catch捕获XML解析错误,单个文件失败不会终止整个批量任务。
  • 无额外依赖:使用Windows原生PowerShell命令,导出的CSV文件可直接用Excel打开,无需安装任何额外软件。

使用说明

  1. 将脚本保存为Extract-WavMetadata.ps1。
  2. 修改$directory为你的WAV文件所在文件夹路径,$outputCsv为导出CSV的路径。
  3. 根据你的实际XML结构,调整脚本中$metadata的字段(比如XML节点是<call_id>就改成$recordingNode.call_id)。
  4. 打开PowerShell,进入脚本所在目录,运行命令:.\Extract-WavMetadata.ps1。

内容的提问来源于stack exchange,提问作者Sam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 23:20:20