ffmpeg学习——音频源

Posted fun binary

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ffmpeg学习——音频源相关的知识,希望对你有一定的参考价值。

一、abuffer

缓冲音频帧,作为滤镜链图中有效的组成(起点)

它主要编程使用,特别是通过中的接口进行调用。

接受如下参数:

  • time_base:用于提交帧的时间戳时基。是浮点数或者分数形式。
  • sample_rate:进入音频缓冲的采样率。
  • sample_fmt:进入音频缓冲的采样格式。下枚举值中的一个格式名称或者对应的整数
  • channel_layout:进入音频缓冲的通道布局。为中的定义的布局名称或者中 类宏(对应的整数表示)
  • channels:进入缓冲的通道数。如果 和 同时被设置,则二者必须一致。

示例

abuffer=sample_rate=44100:sample_fmt=s16p:channel_layout=stereo

源接受信号立体声(采样率44100HZ)。

采样格式:s16p即6

通道布局:stereo,即0x3

abuffer=sample_rate=44100:sample_fmt=6:channel_layout=0x3

二、aevalsrc

按表达式生成一个音频信号(信号发生器)

它接受一个或者多个表达式(每个对应一个通道),根据表达式计算产生相应的音频信号。

接受如下的选项:

  • exprs:由’|’分隔的表达式列表,每个表达式对应一个通道。以防没有指定选项,选中的通道布局取决于提供的数量表达式。否则最后指定表达式应用于剩下的输出通道。
  • channel_layout, c:设置通道布局。这里的通道数必须等于表达式数量。
  • duration, d:设置源音频持续时间。参考内容以了解语法。注意由此生成的音频持续时间可能会超过这里指定的时间,因为生成的音频最少是一个完整的帧内容。如果不指定,或者指定一个非负数,表面会持续生成音频信号。
  • nb_samples, n:设置每个输出帧中每个通道的样例数量,默认1024。
  • sample_rate, s:指定采样频率,默认44100.

每个表达式可以包含下面的常量:

  • n:评估样本的数量,从0开始计数
  • t:样本时间表示,从0开始计时
  • s:样本采样率

示例

生成静音(无声)

ffmpeg -f lavfi -i aevalsrc=0 -t 10 1.mp3

生成频率为440Hz的正弦波,采样频率8000Hz:

ffmpeg -f lavfi -i aevalsrc="sin(440*2*PI*t):s=8000" -t 10 1.mp3

生成双路信号,这里指定为(中前和中后),表达式为:

ffmpeg -f lavfi -i aevalsrc="sin(420*2*PI*t)|cos(430*2*PI*t):c=FC|BC" -t 10 1.mp3

生成白噪声:

ffmpeg -f lavfi -i aevalsrc="-2+random(0)" -t 10 1.mp3

生成一个振幅调制信号:

ffmpeg -f lavfi -i aevalsrc="sin(10*2*PI*t)*sin(880*2*PI*t)" -t 10 1.mp3

生成2.5赫兹双耳节拍在360赫兹的载体:

ffmpeg -f lavfi -i aevalsrc="0.1*sin(2*PI*(360-2.5/2)*t) | 0.1*sin(2*PI*(360+2.5/2)*t)" -t 10 1.mp3

三、afirsrc

使用频率采样方法生成 FIR 系数。

生成的流可以与过滤器一起用于过滤音频信号。

过滤器接受以下选项:

  • taps, t:在输出音频流中设置过滤器系数的数量。默认值为 1025。
  • frequency, f:设置频率点,从中设置幅度和相位。这必须是非降序,第一个元素必须为 0,最后一个元素必须为 1。元素之间用空格分隔。
  • magnitude, m:为每个频率点设置幅度值频率. 值的数量必须与频点的数量相同。值由空格分隔。
  • phase, p:为每个频率点设置相位值频率. 值的数量必须与频点的数量相同。值由空格分隔。
  • sample_rate, r:设置采样率,默认为 44100。
  • nb_samples, n:设置每帧的样本数。默认值为 1024。
  • win_func, w:设置窗口功能。默认为blackman。

四、anullsrc

null(空)音频源会产生未处理的音频帧。它一般用于分析/调试,或作为滤镜可忽略的输入源(例如合成滤镜)

这个源接受下面选项:

  • channel_layout, cl:指定通道布局,可以是整数或对应的短语,默认为。定义channel_layout1
  • sample_rate, r:采样率,默认 44100。
  • nb_samples, n:每帧的样本数。
  • duration, d:设置源音频持续时间。参考内容以了解语法。注意由此生成的音频持续时间可能会超过这里指定的时间,因为生成的音频最少是一个完整的帧内容。如果不指定,或者指定一个非负数,表面会持续生成音频信号。

示例

以采样率48000 Hz ,单声道().

ffmpeg -f lavfi -i anullsrc=r=44100:cl=4 -t 10 1.mp3
等价于
ffmpeg -f lavfi -i anullsrc=r=44100:cl=mono -t 10 1.mp3

五、flite

使用libflite库合成声音话语。

编译选项是

库不是线程安全的。

接受如下选项:

  • list_voices:如果为1,列出有效的语音并退出,默认0。
  • nb_samples, n:设置每个帧最大样例数量,默认512。
  • textfile:设置要朗读的文件名。
  • text:设置要朗读的文本。
  • voice, v:设置语音合成的声音,默认参考选项

示例

从文件speech.txt读,使用标准声音合成:

flite=textfile=speech.txt

读取指定文本,并用语音合成:

flite=text='So fare thee well, poor devil of a Sub-Sub, whose commentator I am':voice=slt

作为ffmpeg输入:

ffmpeg -f lavfi -i flite=text='So fare thee well, poor devil of a Sub-Sub, whose commentator I am':voice=slt

播放合成语音:

ffplay -f lavfi flite=text='No more be grieved for which that thou hast done.'

更多

关于库的更多信息,确认

六、anoisesrc

产生噪声音频信号。

接受下列选项

  • sample_rate、r:采样率,默认48000HZ。
  • amplitude, a:指定生成的音频流的振幅(0.0 - 1.0)。默认1.0。
  • duration, d:指定生成的音频流的持续时间。不指定此选项会导致噪音的长度无穷大。
  • color, colour, c:指定噪声的颜色。可用的噪声颜色有白色、粉色、棕色、蓝色、紫色和天鹅绒色。默认颜色是白色。
  • seed, s:指定一个用于播种PRNG的值。
  • nb_samples, n:设置每个输出帧的采样数量,默认是1024。

示例

产生60秒的粉色噪声,44.1 kHz的采样率和0.5的振幅:

  • anoisesrc=d=60:c=pink:r=44100:a=0.5
    

七、hilbert

生成odd-tap Hilbert变换FIR系数。

产生的流可以使用滤波器相移信号90度。

这在许多矩阵编码方案和分析信号生成中被使用。这个过程通常被写成乘以虚数单位i(或j)。

过滤器接受以下选项:

  • sample_rate, s:采样率,默认44100。

  • taps, t:设置FIR滤波器长度,默认22051。

  • nb_samples, n:设置每个输出帧的采样数量。

  • win_func, w:设置生成FIR系数时使用的窗口函数。

八、sinc

生成一个音频信号的振幅的正弦波1/8

是一个bit-exact音频信号(脉冲?)

接受如下选项:

  • frequency, f:设置载波频率,默认 440 Hz.
  • beep_factor, b:每个倍载波频率周期产生一个,默认为0,表示被禁止
  • sample_rate, r:指定采样率,默认44100.
  • duration, d:指定产生音频持续时间
  • samples_per_frame:设置每帧样例数,默认1024

示例

产生440Hz的波Generate a simple 440 Hz sine wave:

sine

产生220Hz波,且880Hz产生一个,持续5秒:

sine=220:4:d=5 sine=f=220:b=4:d=5 sine=frequency=220:beep_factor=4:duration=5

附录

channel_layout

static const struct channel_layout_name channel_layout_map[] = 
     "mono",           AV_CHANNEL_LAYOUT_MONO                , 
     "stereo",         AV_CHANNEL_LAYOUT_STEREO              ,
     "2.1",            AV_CHANNEL_LAYOUT_2POINT1             ,
     "3.0",            AV_CHANNEL_LAYOUT_SURROUND            ,
     "3.0(back)",      AV_CHANNEL_LAYOUT_2_1                 ,
     "4.0",            AV_CHANNEL_LAYOUT_4POINT0             ,
     "quad",           AV_CHANNEL_LAYOUT_QUAD                ,
     "quad(side)",     AV_CHANNEL_LAYOUT_2_2                 ,
     "3.1",            AV_CHANNEL_LAYOUT_3POINT1             ,
     "5.0",            AV_CHANNEL_LAYOUT_5POINT0_BACK        ,
     "5.0(side)",      AV_CHANNEL_LAYOUT_5POINT0             ,
     "4.1",            AV_CHANNEL_LAYOUT_4POINT1             ,
     "5.1",            AV_CHANNEL_LAYOUT_5POINT1_BACK        ,
     "5.1(side)",      AV_CHANNEL_LAYOUT_5POINT1             ,
     "6.0",            AV_CHANNEL_LAYOUT_6POINT0             ,
     "6.0(front)",     AV_CHANNEL_LAYOUT_6POINT0_FRONT       ,
     "hexagonal",      AV_CHANNEL_LAYOUT_HEXAGONAL           ,
     "6.1",            AV_CHANNEL_LAYOUT_6POINT1             ,
     "6.1(back)",      AV_CHANNEL_LAYOUT_6POINT1_BACK        ,
     "6.1(front)",     AV_CHANNEL_LAYOUT_6POINT1_FRONT       ,
     "7.0",            AV_CHANNEL_LAYOUT_7POINT0             ,
     "7.0(front)",     AV_CHANNEL_LAYOUT_7POINT0_FRONT       ,
     "7.1",            AV_CHANNEL_LAYOUT_7POINT1             ,
     "7.1(wide)",      AV_CHANNEL_LAYOUT_7POINT1_WIDE_BACK   ,
     "7.1(wide-side)", AV_CHANNEL_LAYOUT_7POINT1_WIDE        ,
     "octagonal",      AV_CHANNEL_LAYOUT_OCTAGONAL           ,
     "hexadecagonal",  AV_CHANNEL_LAYOUT_HEXADECAGONAL       ,
     "downmix",        AV_CHANNEL_LAYOUT_STEREO_DOWNMIX,     ,
     "22.2",           AV_CHANNEL_LAYOUT_22POINT2,           ,
;

AVSampleFormat

enum AVSampleFormat 
    AV_SAMPLE_FMT_NONE = -1,
    AV_SAMPLE_FMT_U8,          ///< unsigned 8 bits
    AV_SAMPLE_FMT_S16,         ///< signed 16 bits
    AV_SAMPLE_FMT_S32,         ///< signed 32 bits
    AV_SAMPLE_FMT_FLT,         ///< float
    AV_SAMPLE_FMT_DBL,         ///< double

    AV_SAMPLE_FMT_U8P,         ///< unsigned 8 bits, planar
    AV_SAMPLE_FMT_S16P,        ///< signed 16 bits, planar
    AV_SAMPLE_FMT_S32P,        ///< signed 32 bits, planar
    AV_SAMPLE_FMT_FLTP,        ///< float, planar
    AV_SAMPLE_FMT_DBLP,        ///< double, planar
    AV_SAMPLE_FMT_S64,         ///< signed 64 bits
    AV_SAMPLE_FMT_S64P,        ///< signed 64 bits, planar

    AV_SAMPLE_FMT_NB           ///< Number of sample formats. DO NOT USE if linking dynamically
;

持续时间

它有两种表示方式:

  • 表示小时数,表示分钟数(最多2位数字)表示秒数(也最多2位数字),是的小数位值
  • 是秒的数值,是的小数位值。

两种语法前面都可选号,表示负数持续时间。

推荐一个零声学院免费教程,个人觉得老师讲得不错,
分享给大家:Linux,
nginx,ZeroMQ,mysql,Redis,
fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,
TCP/IP,协程,DPDK等技术内容,点击立即学习


  1. channel_layout

    static const struct channel_layout_name channel_layout_map[] = 
         "mono",           AV_CHANNEL_LAYOUT_MONO                , 
         "stereo",         AV_CHANNEL_LAYOUT_STEREO              ,
         "2.1",            AV_CHANNEL_LAYOUT_2POINT1             ,
         "3.0",            AV_CHANNEL_LAYOUT_SURROUND            ,
         "3.0(back)",      AV_CHANNEL_LAYOUT_2_1                 ,
         "4.0",            AV_CHANNEL_LAYOUT_4POINT0             ,
         "quad",           AV_CHANNEL_LAYOUT_QUAD                ,
         "quad(side)",     AV_CHANNEL_LAYOUT_2_2                 ,
         "3.1",            AV_CHANNEL_LAYOUT_3POINT1             ,
         "5.0",            AV_CHANNEL_LAYOUT_5POINT0_BACK        ,
         "5.0(side)",      AV_CHANNEL_LAYOUT_5POINT0             ,
         "4.1",            AV_CHANNEL_LAYOUT_4POINT1             ,
         "5.1",            AV_CHANNEL_LAYOUT_5POINT1_BACK        ,
         "5.1(side)",      AV_CHANNEL_LAYOUT_5POINT1             ,
         "6.0",            AV_CHANNEL_LAYOUT_6POINT0             ,
         "6.0(front)",     AV_CHANNEL_LAYOUT_6POINT0_FRONT       ,
         "hexagonal",      AV_CHANNEL_LAYOUT_HEXAGONAL           ,
         "6.1",            AV_CHANNEL_LAYOUT_6POINT1             ,
         "6.1(back)",      AV_CHANNEL_LAYOUT_6POINT1_BACK        ,
         "6.1(front)",     AV_CHANNEL_LAYOUT_6POINT1_FRONT       ,
         "7.0",            AV_CHANNEL_LAYOUT_7POINT0             ,
         "7.0(front)",     AV_CHANNEL_LAYOUT_7POINT0_FRONT       ,
         "7.1",            AV_CHANNEL_LAYOUT_7POINT1             ,
         "7.1(wide)",      AV_CHANNEL_LAYOUT_7POINT1_WIDE_BACK   ,
         "7.1(wide-side)", AV_CHANNEL_LAYOUT_7POINT1_WIDE        ,
         "octagonal",      AV_CHANNEL_LAYOUT_OCTAGONAL           ,
         "hexadecagonal",  AV_CHANNEL_LAYOUT_HEXADECAGONAL       ,
         "downmix",        AV_CHANNEL_LAYOUT_STEREO_DOWNMIX,     ,
         "22.2",           AV_CHANNEL_LAYOUT_22POINT2,           ,
    ;
    
    ↩︎

使用PowerShell和FFMPEG将音频和字幕源条带化并添加到INDEX.M3U8

我正在使用自定义脚本将视频文件转换为多分辨率HLS。我已切换到新的网络播放器,它将允许我支持字幕轨道和音频轨道选择。

[我很难弄清楚如何编辑脚本以使用.MKV并剥离所有音频源和字幕源并将其添加到INDEX.M3U8

我当前的脚本:

$sw = [Diagnostics.Stopwatch]::StartNew()
$files = Get-ChildItem ${Get-Location}
$loco = Get-Location
$p1 = Join-Path -Path $loco -ChildPath "/out"
echo $p1
New-Item -ItemType Directory -Force -Path $p1
foreach ($f in $files){ 
$p2 = Join-Path -Path $loco -ChildPath "/out/" | Join-Path -ChildPath $f
$sb = [System.Text.StringBuilder]::new();
[void]$sb.AppendLine( '#EXTM3U' )
[void]$sb.AppendLine( '#EXT-X-VERSION:3' )
[void]$sb.AppendLine( '#EXT-X-STREAM-INF:BANDWIDTH=800000,RESOLUTION=640x360' )
[void]$sb.AppendLine( '360p.m3u8' )
[void]$sb.AppendLine( '#EXT-X-STREAM-INF:BANDWIDTH=1400000,RESOLUTION=842x480' )
[void]$sb.AppendLine( '480.m3u8' )

New-Item -ItemType Directory -Force -Path $p2
$resStr = ffprobe -v error -select_streams v:0 -show_entries stream=height -of csv=s=x:p=0 $f.FullName;
$res = [convert]::ToInt32($resStr)
#ffmpeg -i $f.FullName -c:a copy -vf scale=w=640:h=360:force_original_aspect_ratio=decrease -c:a aac -ar 48000  -rc cqp -qp_p 0 -qp_i 1 -profile:v main -crf 20 -sc_threshold 0 -g 48 -keyint_min 48 -hls_time 4 -hls_playlist_type vod  -b:v 800k -maxrate 856k -bufsize 1200k -b:a 96k -hls_segment_filename out/$f/360p_%03d.ts out/$f/360p.m3u8 -vf scale=w=842:h=480:force_original_aspect_ratio=decrease -c:a aac -ar 48000 -gpu 1 -c:v h264_amf -rc cqp -qp_p 0 -qp_i 1 -profile:v main -crf 20 -sc_threshold 0 -g 48 -keyint_min 48 -hls_time 4 -hls_playlist_type vod -b:v 1400k -maxrate 1498k -bufsize 2100k -b:a 128k -hls_segment_filename out/$f/480p_%03d.ts out/$f/480p.m3u8 -vf  scale=w=1280:h=720:force_original_aspect_ratio=decrease -c:a aac -ar 48000 -gpu 1 -c:v h264_amf -rc cqp -qp_p 0 -qp_i 1 -profile:v main -crf 20 -sc_threshold 0 -g 48 -keyint_min 48 -hls_time 4 -hls_playlist_type vod -b:v 2800k -maxrate 2996k -bufsize 4200k -b:a 128k -hls_segment_filename out/$f/720p_%03d.ts out/$f/720p.m3u8 -vf  scale=w=1920:h=1080:force_original_aspect_ratio=decrease -c:a aac -ar 48000 -gpu 1 -c:v h264_amf -rc cqp -qp_p 0 -qp_i 1 -profile:v main -crf 20 -sc_threshold 0 -g 48 -keyint_min 48 -hls_time 4 -hls_playlist_type vod -b:v 5000k -maxrate 5350k -bufsize 7500k -b:a 192k -hls_segment_filename out/$f/1080p_%03d.ts out/$f/1080p.m3u8
#ffmpeg -hwaccel auto -hwaccel_device 0 -i $f.FullName -c:v h264 -profile:v main -c:a aac -filter:v scale=360:640 -ar 48000  -rc cqp -qp_p 0 -qp_i 1 -profile:v main -crf 23 -sc_threshold 0 -g 48 -b:v 800k -maxrate 856k -bufsize 1200k -b:a 96k  -keyint_min 4 -start_number 0 -hls_time 10 -hls_playlist_type vod  -hls_list_size 0 -f hls -hls_segment_filename out/$f/360p_%03d.ts out/$f/360p.m3u8 
ffmpeg -hwaccel auto -hwaccel_device 0 -i $f.FullName -c:v h264_nvenc -b:v 200k -minrate 100k -maxrate 896k -profile:v main -c:a aac -filter:v scale=-1:360 -start_number 0 -hls_time 10 -hls_list_size 0 -f hls -hls_segment_filename out/$f/360p_%03d.ts out/$f/360p.m3u8 
ffmpeg -hwaccel auto -hwaccel_device 0 -i $f.FullName -c:v h264_nvenc -b:v 1000k -minrate 896k -maxrate 1536k -profile:v main -c:a aac -filter:v scale=-1:480 -start_number 0 -hls_time 10 -hls_list_size 0 -f hls -hls_segment_filename out/$f/480p_%03d.ts out/$f/480p.m3u8
If($res -ge 720) {
    ffmpeg -hwaccel auto -hwaccel_device 0 -i $f.FullName -c:v h264_nvenc -b:v 2232k -minrate 1856k -maxrate 2872k -profile:v main -c:a aac -filter:v scale=-1:720 -start_number 0 -hls_time 10 -hls_list_size 0 -f hls -hls_segment_filename out/$f/720p_%03d.ts out/$f/720p.m3u8
    [void]$sb.AppendLine( '#EXT-X-STREAM-INF:BANDWIDTH=2800000,RESOLUTION=1280x720' )
    [void]$sb.AppendLine( '720p.m3u8' )
}   
If($res -ge 1080) {
    ffmpeg -hwaccel auto -hwaccel_device 0 -i $f.FullName -c:v h264_nvenc -b:v 4632k -minrate 3712k -maxrate 5552k -profile:v main -c:a aac -filter:v scale=-1:1080 -start_number 0 -hls_time 10 -hls_list_size 0 -f hls -hls_segment_filename out/$f/1080p_%03d.ts out/$f/1080p.m3u8
    [void]$sb.AppendLine( '#EXT-X-STREAM-INF:BANDWIDTH=5000000,RESOLUTION=1920x1080' )
    [void]$sb.AppendLine( '1080p.m3u8' )
}

$p3 = Join-Path -Path $p2 -ChildPath "/index.m3u8"
#echo $index | Out-File -Encoding UTF8 -LiteralPath $p3
echo $sb.ToString()
[System.IO.File]::WriteAllLines($p3, $sb.ToString().Trim().replace("`r`n", "`n"))
 }
 $sw.Stop()
 echo $sw.Elapsed
答案
$sw = [Diagnostics.Stopwatch]::StartNew()
$files = Get-ChildItem ${Get-Location}
$loco = Get-Location
$p1 = Join-Path -Path $loco -ChildPath "/out"
New-Item -ItemType Directory -Force -Path $p1



function lnCodeTransform {
param( $String )
echo $String
switch ($String)
{
    "jpn" {"jp"}
    "eng" {"en"}
    "esp" {"es"}
    "fra" {"fr"}
    "deu" {"de"}
    default {$String}
}
}


function lnNameTransform {
param( $String )
switch ($String)
{
    "jpn" {"Japanese"}
    "eng" {"English"}
    "esp" {"Spanish"}
    "fra" {"French"}
    "deu" {"German"}
    default {$String}
}
}


foreach ($f in $files){ 
if ($f.Name -eq "out"){
    continue;
}
$p2 = Join-Path -Path $loco -ChildPath "/out/" | Join-Path -ChildPath $f
New-Item -ItemType Directory -Force -Path $p2/audio
New-Item -ItemType Directory -Force -Path $p2/video
New-Item -ItemType Directory -Force -Path $p2/subtitle
$sb = [System.Text.StringBuilder]::new();
[void]$sb.AppendLine( '#EXTM3U' )
[void]$sb.AppendLine( '#EXT-X-VERSION:3' )
#[void]$sb.AppendLine( '#EXT-X-STREAM-INF:BANDWIDTH=800000,RESOLUTION=640x360' )
#[void]$sb.AppendLine( '360p.m3u8' )


New-Item -ItemType Directory -Force -Path $p2
$resStr = ffprobe -v error -select_streams v:0 -show_entries stream=height -of csv=s=x:p=0 $f.FullName;
$res = [convert]::ToInt32($resStr)
$audioTracks = ffprobe $f.FullName -show_entries stream=index:stream_tags=language -select_streams a -of compact=p=0:nk=1 
$audioTracks = $audioTracks.split("
")
foreach($audio in $audioTracks) {
    $ID = $audio.split("|")[0];
    $audioName = $audio.split("|")[1];
    ffmpeg -i $f.FullName -threads 0 -muxdelay 0 -y -map 0:$ID -codec aac -f segment -segment_time 10 -segment_list_size 0 -segment_list out/$f/audio/audio_"$ID.m3u8" -segment_format mpegts out/$f/audio/"audio_$ID""_%d.ts"
    $name = lnNameTransform($audioName)
    $code = lnCodeTransform($audioName)
    [void]$sb.AppendLine( "#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID=`"aac`",LANGUAGE=`"$code`",NAME=`"$name`",DEFAULT=NO,AUTOSELECT=NO,URI=`"audio/audio_$ID.m3u8`"" )
}
$subTracks = ffprobe $f.FullName -show_entries stream=index:stream_tags=language -select_streams s -of compact=p=0:nk=1 
$subTracks = $subTracks.split("")
foreach($subtitle in $subTracks) {
    $ID = $subtitle.split("|")[0];
    $subName = $subtitle.split("|")[1];
    ffmpeg -i $f.FullName -map 0:$ID -f segment -segment_time 10 -segment_list_size 0 -segment_list out/$f/subtitle/sub_"$subName.m3u8" -segment_format webvtt -scodec webvtt out/$f/subtitle/"sub_$subName%d.vtt"
    $name = lnNameTransform($subName)
    $code = lnCodeTransform($subName)
    [void]$sb.AppendLine( "#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID=`"subs`",LANGUAGE=`"$code`",NAME=`"$name`",FORCED=NO,AUTOSELECT=NO,URI=`"subtitle/sub_$subName.m3u8`"" )
}

[void]$sb.AppendLine( '#EXT-X-STREAM-INF:BANDWIDTH=1400000,CODECS="avc1.4d4015,mp4a.40.2",RESOLUTION=842x480,AUDIO="aac",SUBTITLES="subs"' )
[void]$sb.AppendLine( 'video/480p.m3u8' )
#ffmpeg -i $f.FullName -c:a copy -vf scale=w=640:h=360:force_original_aspect_ratio=decrease -c:a aac -ar 48000  -rc cqp -qp_p 0 -qp_i 1 -profile:v main -crf 20 -sc_threshold 0 -g 48 -keyint_min 48 -hls_time 4 -hls_playlist_type vod  -b:v 800k -maxrate 856k -bufsize 1200k -b:a 96k -hls_segment_filename out/$f/360p_%03d.ts out/$f/360p.m3u8 -vf scale=w=842:h=480:force_original_aspect_ratio=decrease -c:a aac -ar 48000 -gpu 1 -c:v h264_amf -rc cqp -qp_p 0 -qp_i 1 -profile:v main -crf 20 -sc_threshold 0 -g 48 -keyint_min 48 -hls_time 4 -hls_playlist_type vod -b:v 1400k -maxrate 1498k -bufsize 2100k -b:a 128k -hls_segment_filename out/$f/480p_%03d.ts out/$f/480p.m3u8 -vf  scale=w=1280:h=720:force_original_aspect_ratio=decrease -c:a aac -ar 48000 -gpu 1 -c:v h264_amf -rc cqp -qp_p 0 -qp_i 1 -profile:v main -crf 20 -sc_threshold 0 -g 48 -keyint_min 48 -hls_time 4 -hls_playlist_type vod -b:v 2800k -maxrate 2996k -bufsize 4200k -b:a 128k -hls_segment_filename out/$f/720p_%03d.ts out/$f/720p.m3u8 -vf  scale=w=1920:h=1080:force_original_aspect_ratio=decrease -c:a aac -ar 48000 -gpu 1 -c:v h264_amf -rc cqp -qp_p 0 -qp_i 1 -profile:v main -crf 20 -sc_threshold 0 -g 48 -keyint_min 48 -hls_time 4 -hls_playlist_type vod -b:v 5000k -maxrate 5350k -bufsize 7500k -b:a 192k -hls_segment_filename out/$f/1080p_%03d.ts out/$f/1080p.m3u8
#ffmpeg -hwaccel auto -hwaccel_device 0 -i $f.FullName -c:v h264_nvenc -preset slow -pix_fmt yuv420p -c:a aac -filter:v scale=360:640 -ar 48000  -rc cqp -qp_p 0 -qp_i 1 -profile:v main -crf 23 -sc_threshold 0 -g 48 -b:v 800k -maxrate 856k -bufsize 1200k -b:a 96k  -keyint_min 4 -start_number 0 -hls_time 10 -hls_playlist_type vod  -hls_list_size 0 -f hls -hls_segment_filename out/$f/360p_%03d.ts out/$f/360p.m3u8 
#ffmpeg -hwaccel auto -hwaccel_device 0 -i $f.FullName -c:v h264 -profile:v main -c:a aac -filter:v scale=360:640 -start_number 0 -hls_time 10 -hls_list_size 0 -f hls -hls_segment_filename out/$f/360p_%03d.ts out/$f/360p.m3u8 
ffmpeg -i $f.FullName -c:v h264_nvenc -crf 22 -preset slow -pix_fmt yuv420p -filter:v scale="trunc(oh*a/2)*2:480" -map 0:v -start_number 0 -hls_time 10 -hls_list_size 0 -f hls -hls_segment_filename out/$f/video/480p_%03d.ts out/$f/video/480p.m3u8
If($res -ge 720) {
    ffmpeg -i $f.FullName -c:v h264_nvenc -crf 20 -preset slow -pix_fmt yuv420p -filter:v scale="trunc(oh*a/2)*2:720" -map 0:v -start_number 0 -hls_time 10 -hls_list_size 0 -f hls -hls_segment_filename out/$f/video/720p_%03d.ts out/$f/video/720p.m3u8
    [void]$sb.AppendLine( '#EXT-X-STREAM-INF:BANDWIDTH=2800000,CODECS="avc1.4d4015,mp4a.40.2",RESOLUTION=1280x720,AUDIO="aac",SUBTITLES="subs"' )
    [void]$sb.AppendLine( 'video/720p.m3u8' )
}   
If($res -ge 1080) {
    ffmpeg -i $f.FullName -c:v h264_nvenc -crf 18 -preset slow -pix_fmt yuv420p -filter:v scale="trunc(oh*a/2)*2:1080" -map 0:v -start_number 0 -hls_time 10 -hls_list_size 0 -f hls -hls_segment_filename out/$f/video/1080p_%03d.ts out/$f/video/1080p.m3u8
    [void]$sb.AppendLine( '#EXT-X-STREAM-INF:BANDWIDTH=5000000,CODECS="avc1.4d4015,mp4a.40.2",RESOLUTION=1920x1080,AUDIO="aac",SUBTITLES="subs"' )
    [void]$sb.AppendLine( 'video/1080p.m3u8' )
}

$p3 = Join-Path -Path $p2 -ChildPath "/index.m3u8"
#echo $index | Out-File -Encoding UTF8 -LiteralPath $p3
echo $sb.ToString()
[System.IO.File]::WriteAllLines($p3, $sb.ToString().Trim().replace("`r`n", "`n"))
}
$sw.Stop()
echo $sw.Elapsed

以上是关于ffmpeg学习——音频源的主要内容,如果未能解决你的问题,请参考以下文章

FFmpeg学习5:多线程播放视音频

第十章 视频播放器开发之音频播放

音视频学习 - QT6.3.1创建QAudioSink+ ffmpeg项目进行音频解析及播放

在 ffmpeg 中使用蓝牙耳机设备作为音频源

Go语学习笔记 - 调用ffmpeg-api实现音频重采样

将各种音频和视频源混合成一个视频