- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试从 m3u8 播放列表文件(在简单的 HLS 中)获取带有音频、视频和字幕的 mp4 视频。
我设法提取了视频和音频流,因为它们相对容易:根据 ffprobe,输入 m3u8 包含 3 个不同的程序,而第三个程序(称为 Program 2)是我需要的,因为它同时包含最高质量的视频和英语最高质量的音频。
所以,我真正在做的是
ffmpeg -i "blahblah.m3u8" -c copy -map 0:p:2:v:0 -map 0:p:2:a:m:language:eng -map 0:s:0 "output.mp4"
这意味着:为第三个(索引 2)节目选择第一个视频流,并从同一个第三个(索引 2)节目中选择英语音频流。
#EXTM3U
# Created with Bento4 mp4-hls.py version 1.2.0r637
#EXT-X-VERSION:4
# Subtitles
#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subtitles",NAME="English",LANGUAGE="en",URI="subtitles/en/subtitles.m3u8"
#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subtitles",NAME="Español",LANGUAGE="es",URI="subtitles/es/subtitles.m3u8"
# Audio
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio_aac",NAME="Français",LANGUAGE="fra",AUTOSELECT=YES,DEFAULT=YES,URI="audio/aac/fra/stream.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio_aac",NAME="English",LANGUAGE="eng",AUTOSELECT=YES,URI="audio/aac/eng/stream.m3u8"
# Media Playlists
#EXT-X-STREAM-INF:AVERAGE-BANDWIDTH=2198120,BANDWIDTH=2416640,CODECS="avc1.4D401F,mp4a.40.2",RESOLUTION=1280x720,AUDIO="audio_aac",SUBTITLES="subtitles"
media-1/stream.m3u8
#EXT-X-STREAM-INF:AVERAGE-BANDWIDTH=1001663,BANDWIDTH=1102896,CODECS="avc1.42C01E,mp4a.40.2",RESOLUTION=640x360,AUDIO="audio_aac",SUBTITLES="subtitles"
media-2/stream.m3u8
#EXT-X-STREAM-INF:AVERAGE-BANDWIDTH=4007581,BANDWIDTH=4391894,CODECS="avc1.4D4029,mp4a.40.2",RESOLUTION=1920x1080,AUDIO="audio_aac",SUBTITLES="subtitles"
media-3/stream.m3u8
我认为这很容易:我添加了
-map 0:s:0
获得第一个字幕,但 ffmpeg 告诉我没有这样命名的流。
ffprobe "blahblah.m3u8" -show_streams -select_streams s
You can find here all the streams which the ffprobe command shows .有很多视频和音频流,但没有字幕流。
最佳答案
$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 )
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,title -select_streams a -of compact=p=0:nk=1
$audioTracks = $audioTracks.split("\r")
foreach($audio in $audioTracks) {
$splited = $audio.split("|");
$ID = $splited[0]
$audioName = $splited[1];
$title = $splited[2];
ffmpeg -i $f.FullName -ss 0 -y -map 0:$ID -start_number 0 -acodec aac -b:a 320k -ac 2 -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 ($title)`",DEFAULT=NO,AUTOSELECT=NO,URI=`"audio/audio_$ID.m3u8`"" )
}
$subTracks = ffprobe $f.FullName -show_entries stream=index:stream_tags=language,title -select_streams s -of compact=p=0:nk=1
$subTracks = $subTracks.split("\r")
foreach($subtitle in $subTracks) {
$splited = $subtitle.split("|");
$ID = $splited[0];
$subName = $splited[1];
$title = $splited[2];
ffmpeg -i $f.FullName -ss 0 -map 0:$ID -f segment -segment_time 10 -segment_list_size 0 -segment_list out/$f/subtitle/sub_"$ID.m3u8" -segment_format webvtt -scodec webvtt out/$f/subtitle/"sub_$ID%d.vtt"
$name = lnNameTransform($subName)
$code = lnCodeTransform($subName)
[void]$sb.AppendLine( "#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID=`"subs`",LANGUAGE=`"$code`",NAME=`"$name ($title)`",FORCED=NO,AUTOSELECT=NO,URI=`"subtitle/sub_$ID.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 -profile:v main -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 -pix_fmt yuv420p -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 -crf 23 -b:v 1200k -minrate 500k -maxrate 2100k -profile:v main -pix_fmt yuv420p -y -filter:v scale=-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
ffmpeg -i $f.FullName -c:v h264_qsv -preset slow -global_quality 30 -look_ahead 1 -profile:v main -level:v 4.1 -rc:v vbr_hq -rc-lookahead:v 32 -pix_fmt yuv420p -y -filter:v scale=-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_qsv -crf 23 -b:v 2400k -minrate 1200k -maxrate 4200k -profile:v main -pix_fmt yuv420p -filter:v scale=-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
ffmpeg -i $f.FullName -c:v h264_qsv -preset slow -global_quality 28 -look_ahead 1 -profile:v main -level:v 4.1 -rc:v vbr_hq -rc-lookahead:v 32 -pix_fmt yuv420p -filter:v scale=-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 900) {
#ffmpeg -i $f.FullName -c:v h264 -crf 30 -b:v 4800k -minrate 2000k -maxrate 8400k -profile:v main -pix_fmt yuv420p -filter:v scale=-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
ffmpeg -i $f.FullName -c:v h264_qsv -preset slow -global_quality 26 -look_ahead 1 -profile:v main -level:v 4.1 -rc:v vbr_hq -rc-lookahead:v 32 -pix_fmt yuv420p -filter:v scale=-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
这是我用来将文件转换为 HLS 并生成 index.m3u8 文件的脚本。是的,您需要编辑索引,但它会完成所有工作。此脚本也使用 Intel gpu。您可以删除 _qsv 以使其在任何 CPU 上工作
关于Ffmpeg 和 ffprobe 未在 m3u8 文件中显示字幕流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67482947/
我想显示阿拉伯文字,但字符 المملك 显示。 例如,在 المملكة العربية السعودية 上显示单词 المملك٩ ا
我的应用程序正在 java + MSSQL 和 MySQL 上运行。下面的查询适用于 MSSQL,但不适用于 MySql。在 mysql 中,当我编写如下查询时,它给出了错误的结果 查询 select
根据 is_destructible 的定义( http://eel.is/c++draft/meta.unary.prop#lib:is_destructible ), is_destructib
我有一个数据库表,其中有一列我对波斯字母进行了分类,以便稍后使用 MySQL WHERE 选择。一切都适用于所有字母,但我在选择在数据库中存储为 (Ù†) 的字母 (?) 和存储为 (Ú†) 的 (?
我知道像这样的可选链接: someOptional?.someProperty 基本上是 someOptional.map { $0.someProperty } 但是,我发现同时做这两件事是不可能的
u-boot配置文件中的以下配置我看不懂 CONFIG_SYS_EXTRA_OPTIONS="SYS_SDRAM_SIZE=0x20000000" 好像在 u-boot 代码中设置 DRAM 大小。但
我对以下两个方法声明感到困惑: private T funWorks(T child, U parent) { // No compilation errors }
给定如下 API: class Bar { ... } class Foo extends Bar { ... } 在 Java 的 Optional 类型中,我们可以说: Optional fooO
我有一个文件,每行有两个字符: $ cat roman Ⅱ Ⅲ nut 当我用 sort -u 对这个文件进行排序时,只显示一行: $ sort -u roman Ⅱ Ⅱ是代码点U+2161,Ⅲ是代码
我正在尝试将 C 数组分配给 C++ std::array。 我该如何做到这一点,最干净的方式并且不制作不需要的拷贝等? 什么时候做 int X[8]; std::array Y = X; 我得到一个
我有以下案例类: case class [Q Length[T] 但是,我收到一条错误消息,说 需要三个参数,而我只给出了两个。我希望它像这样工作: type Area[T] = [Length[T
它是 well documented那个[T; n]可以强制到[T] .下面的代码也是well-formed : fn test(){ let _a: &[i32] = &[1, 2, 3];
我正在尝试使用 tweepy 在 Tkinter 窗口上显示我的 Twitter 时间线。这是代码 import tweepy import tkinter consumer_key = 'xxxxx
我正在使用以下包含 letter ü 的文本片段: test für fur test 代码如下: import re for m in re.finditer(r, line, re.IGNOREC
我对 USQL 很陌生,想知道如何在 select 语句中将“日期时间”转换为“日期”。另外,我如何摆脱毫秒和上午/下午?我真的很感激这方面的任何帮助。谢谢你们。 最佳答案 下面是有效的代码。注意括号
在 U-SQL 自定义代码(代码隐藏或程序集)中可以调用外部服务,例如bing搜索或 map 。 谢谢, 纳西尔 最佳答案 由于以下原因,目前不支持此功能: 想象一下,您编写了一个 UDF 或 UDO
我想 ping 出多个以太网端口。 u-boot 仅支持单个以太网端口是否存在固有限制? 最佳答案 Can u-boot support more than one ethernet port? 是的
我最近开始学习Prolog,但无法解决如何将三个列表合并的问题。 我能够合并两个列表: %element element(X,[X|_]). element(X,[_|Y]):-
我们使用 Beaglebone 黑色定制板。我编辑了一个链接器脚本文件以添加内存部分以在其中记录一些信息: . = ALIGN(4); .logging : { _log_begin
我们使用 Beaglebone 黑色定制板。我编辑了一个链接器脚本文件以添加内存部分以在其中记录一些信息: . = ALIGN(4); .logging : { _log_begin
我是一名优秀的程序员,十分优秀!