-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathadaptation_set.rb
More file actions
133 lines (113 loc) · 3.97 KB
/
adaptation_set.rb
File metadata and controls
133 lines (113 loc) · 3.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# frozen_string_literal: true
require_relative 'hls_class_methods'
require_relative 'representation'
module FFMPEG
module DASH
# Represents an Adaptation Set in a DASH manifest.
class AdaptationSet
include HLSClassMethods
attr_reader :manifest
def initialize(manifest, node)
@manifest = manifest
@node = node
end
# Returns the ID of the adaptation set.
#
# @return [Integer, nil] The ID of the adaptation set.
def id
@id ||= @node['id']&.to_i
end
# Returns the aspect ratio of the adaptation set.
#
# @return [String, nil] The pixel aspect ratio.
def par
@par ||= @node['par']
end
# Returns the language of the adaptation set.
#
# @return [String, nil] The language code (e.g., 'und', 'en', 'fr').
def lang
@lang ||= @node['lang']
end
# Returns the content type of the adaptation set.
#
# @return [String, nil] The content type.
def content_type
@content_type ||= @node['contentType']
end
# Returns the max width of the adaptation set.
#
# @return [Integer, nil] The maximum width in pixels.
def max_width
@max_width ||= @node['maxWidth']&.to_i
end
# Returns the max height of the adaptation set.
#
# @return [Integer, nil] The maximum height in pixels.
def max_height
@max_height ||= @node['maxHeight']&.to_i
end
# Returns the frame rate of the adaptation set.
#
# @return [Rational, nil] The frame rate as a Rational number.
def frame_rate
@frame_rate ||= @node['frameRate']&.to_r
end
# Returns the representations in the adaptation set.
#
# @return [Array<Representation>] An array of Representation objects.
def representations
@representations ||=
@node
.xpath('./xmlns:Representation')
.map { Representation.new(self, _1) }
end
# Sets the base URL for all representations in the adaptation set.
#
# @param value [String] The base URL to set.
# @return [void]
def base_url=(value)
representations.each { _1.base_url = value }
end
# Sets the segment query for all representations in the adaptation set.
#
# @param value [String] The segment query to set.
# @return [void]
def segment_query=(value)
representations.each { _1.segment_query = value }
end
# Returns the representation as a string in M3U8 (HLS playlist) media track format.
# NOTE: Currently we only support audio and video representations.
#
# See https://datatracker.ietf.org/doc/html/rfc8216
#
# @param default [Boolean] Whether to mark media track as default or not.
# @param autoselect [Boolean] Whether to mark media track as automatically selected or not.
# @param group_id [String, nil] The group ID for media track.
# @return [String, nil] The M3U8 EXT-X-MEDIA formatted string for the representation.
def to_m3u8mt(group_id: content_type, default: true, autoselect: true)
return unless %w[audio video].include?(content_type)
return unless representations.any?
url = "stream#{representations.first.id}.m3u8"
url = URI.join(representations.first.base_url, url).to_s if representations.first.base_url
m3u8t(
'EXT-X-MEDIA',
'TYPE' => content_type.upcase,
'GROUP-ID' => quote(group_id),
'NAME' => quote(lang || 'und'),
'LANGUAGE' => quote(lang || 'und'),
'DEFAULT' => default ? 'YES' : 'NO',
'AUTOSELECT' => autoselect ? 'YES' : 'NO',
'URI' => quote(url)
)
end
private
def respond_to_missing?(name, include_private = false)
@node.respond_to?(name, include_private) || super
end
def method_missing(name, *args, &)
@node.send(name, *args, &)
end
end
end
end