分类: FFmpeg

  • 使用FFmpeg和Intel QSV将蓝光原盘转码为HEVC格式以适应网络播放

    由于群晖NAS不再支持Video Station,因此决定将NAS上的蓝光原盘视频转码为适合网络播放的低码率格式。在综合考虑质量和转码速度后,最终选择使用FFmpeg配合Intel Quick Sync Video (QSV)将视频转码为H.265 (HEVC) Main10格式。

    本文为个人笔记,内容简洁,不讨论选择背后的原因。

    硬件配置需求

    该方案至少需要Kaby Lake(7代Intel® Core™)或更新版本的带核显Intel处理器,或Intel® Arc™独立显卡,以便支持QSV硬件加速。

    视频格式情况

    收藏的蓝光原盘视频几乎均为NTSC格式,按以下三种情况处理:

    • 逐行扫描:常见为24p或30p,帧率为24000/1001或30000/1001,此类视频无需额外处理。
    • 隔行扫描:常见为30i,帧率为30000/1001,此类视频需要反交错处理。
    • 24p插帧:视频为30i或30p,帧率为30000/1001,此类视频需进行Inverse Telecine (IVTC)或帧率转换。

    使用vpp_qsv可以智能地选择适当的反交错算法和帧率转换方法,因此无需手动指定处理方式。

    音频处理

    对于流媒体播放的音频部分,使用AAC 48000Hz 256Kbps编码已足够,原盘中如有96000Hz或其他格式的音频,也统一转换为48000Hz处理。由于本人收藏的蓝光原盘主要为电视动画,这里不考虑多音轨的情况。

    Powershell代码

    # 添加 FFmpeg 到 PATH
    $env:PATH += ";$env:PUBLIC\ffmpeg-7.1-full_build\bin"
    
    # 视频输入参数
    $VideoInputParams = @(
        '-init_hw_device', 'qsv:hw,child_device_type=d3d11va',
        '-hwaccel', 'qsv',
        '-hwaccel_output_format', 'qsv',
        '-c:v', 'h264_qsv'
    )
    
    # 视频输出参数
    $VideoOutputParams = @(
        '-c:v', 'hevc_qsv',
        '-global_quality', '25',
        '-extbrc', '1',
        '-b_strategy', '1',
        '-bf', '7',
        '-refs', '4',
        '-g', '256',
        '-fps_mode', 'passthrough'
    )
    
    # 音频输出参数
    $AudioOutputParams = @('-b:a', '256k')
    
    # 音频滤镜
    $AudioFilters = @('-af', 'aresample=resampler=soxr:precision=28:out_sample_rate=48000')
    
    # 选择模式
    Switch (Read-Host "1. HD to HEVC.`n2. HD to HEVC with Deinterlace.`n3. HD to HEVC with IVTC.`n4. HD to HEVC with Audio SRC.`n5. HD to HEVC with Deinterlace & Audio SRC.`n6. HD to HEVC with IVTC & Audio SRC.`n`n`tPlease select a mode") {
        1 { $VideoFilters = @('-vf', 'vpp_qsv=format=p010le') }
        2 { $VideoFilters = @('-vf', 'vpp_qsv=format=p010le:deinterlace=2') }
        3 { $VideoFilters = @('-vf', 'vpp_qsv=format=p010le:deinterlace=2:framerate=24000/1001') }
        4 { $VideoFilters = @('-vf', 'vpp_qsv=format=p010le'); $UseAudioFilters = $true }
        5 { $VideoFilters = @('-vf', 'vpp_qsv=format=p010le:deinterlace=2'); $UseAudioFilters = $true }
        6 { $VideoFilters = @('-vf', 'vpp_qsv=format=p010le:deinterlace=2:framerate=24000/1001'); $UseAudioFilters = $true }
    }
    
    # 处理视频文件
    Get-ChildItem *.m2ts, *.mkv, *.mov | ForEach-Object {
        $params = $VideoInputParams + '-i' + $_.FullName + $VideoFilters + $VideoOutputParams
    
        if ($UseAudioFilters) {
            $params += $AudioFilters
        }
        
        $params += $AudioOutputParams
    
        # 执行 FFmpeg
        try {
            ffmpeg.exe $params -y "$($_.BaseName).mp4"
        } catch {
            Write-Host "Error processing $($_.Name): $_"
        }
    }