此问题涉及HLS播放列表,在潜入之前了解HLS的工作原理可能会有所帮助。
HLS(HTTP Live Streaming)是一个播放列表,类似于iTunes .m3u播放列表。 HLS采用视频文件(例如.mpg),并将其拆分为多个等长段文件(.ts - 代表传输流)。为简单起见,您可以将这些段文件视为原始.mpg文件的块,这些文件将连续播放。
有很多方法可以命名这些段文件。有时你有......
file_segment_0.ts
file_segment_1.ts
file_segment_2.ts
但有时你会有类似的东西,
22/51/04.ts
22/51/09.ts
22/51/14.ts
(H / M / S)
客户端(例如VLC)知道如何处理这些文件。由制作人决定他们如何命名他们的文件。
HLS播放列表也可以是“VOD”(视频点播)或“直播”。如果播放列表为“实时”,则客户端将跳转到当前的实时时间。在播放列表中,标题将定义程序(就流式事件而言)开始日期时间,如下所示:
#EXT-X-PROGRAM-DATE-TIME:2016-09-16T21:59:09+00:00
播放列表还会告诉客户端分段文件的分隔距离,以秒为单位。
我的问题属于H / M / S格式。您可以在此处找到示例播放列表:http://pastebin.com/raw/rS84YJwN
根据#EXTINF:5.005
的定义,这些细分为5.005秒。
EXT-X-PROGRAM-DATE-TIME
开始,按5.005递增,相应地舍入,并将日期格式设为H/M/S.ts
但是有一个更大的问题:为什么EXT-X-PROGRAM-DATE-TIME + 5.005
之间有时会有207个细分,为什么EXT-X-PROGRAM-DATE-TIME + 5.005
之间有时会有196个细分?
我的数学告诉我,每200个段我将增加6(而不是5),我可以用一些快速和脏的ruby代码[0]计算为真,这会生成此输出:
139 22/14/40.ts
339 22/31/21.ts
539 22/48/02.ts
746 23/05/18.ts
946 23/21/59.ts
1146 23/38/40.ts
1346 23/55/21.ts
1402 00/00/01.ts
1542 00/11/42.ts
1742 00/28/23.ts
1942 00/45/04.ts
2142 01/01/45.ts
2342 01/18/26.ts
2542 01/35/07.ts
2742 01/51/48.ts
2942 02/08/29.ts
3142 02/25/10.ts
3342 02/41/51.ts
3542 02/58/32.ts
3749 03/15/48.ts
3949 03/32/29.ts
4149 03/49/10.ts
其中139
是行号,22/14/40.ts
是段文件。
我的问题是:这里发生了什么,如何准确地重现?我显然不会/不会访问实际的输入视频文件,我需要重建这些播放列表文件。
[0]
require 'date'
file = `curl 'http://pastebin.com/raw/rS84YJwN'`
start_date = DateTime.parse(file.scan(%r{#EXT-X-PROGRAM-DATE-TIME:(.*)$}).to_a.first.first)
lines = file.split("\n").select { |line| !line.index('.ts').nil? }
date_lines = []
lines.each_with_index do |line, i|
str = line.gsub("/", ':').split(".ts")[0]
date = "#{start_date.to_date} #{str}"
date_obj = DateTime.parse(date)
date_lines << date_obj
next unless i > 0
diff = date_obj.to_time - date_lines[i - 1].to_time
if diff != 5.0
puts "#{i} #{line}"
end
end