m3uzi 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Brandon Arbini / Zencoder, Inc.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,68 @@
1
+ M3Uzi
2
+ ======
3
+
4
+ Read and write M3U files with (relative) ease.
5
+
6
+ Usage
7
+ ------
8
+
9
+ Read an M3U file:
10
+
11
+ M3Uzi.read("/path/to/file.m3u8")
12
+
13
+ Write an M3U file:
14
+
15
+ m3u.write("/path/to/file.m3u8")
16
+
17
+ Get a list of filenames:
18
+
19
+ m3u.filenames
20
+
21
+ Get all file reference objects:
22
+
23
+ m3u.files
24
+
25
+ Add a file to the M3U index:
26
+
27
+ m3u.add_file do |file|
28
+ file.path = "/path/to/file.ts"
29
+ file.duration = 10
30
+ file.description = "no desc"
31
+ end
32
+
33
+ Get all tag reference objects:
34
+
35
+ m3u.tags
36
+
37
+ Get an individual tag value (TARGETDURATION MEDIA-SEQUENCE ALLOW-CACHE STREAM-INF ENDLIST VERSION):
38
+
39
+ m3u[:targetduration]
40
+ m3u[:media_sequence]
41
+
42
+ Set an individual tag value:
43
+
44
+ m3u[:targetduration] = 100
45
+
46
+ Add a tag to the M3U index:
47
+
48
+ m3u.add_tag do |tag|
49
+ tag.name = "VERSION"
50
+ tag.value = "1"
51
+ end
52
+
53
+
54
+ NOTES
55
+ ------
56
+ * Target duration will be calculated and included if omitted
57
+
58
+
59
+ TODO
60
+ -----
61
+
62
+ * Tags KEY, PROGRAM-DATE-TIME, and DISCONTINUITY are not supported
63
+ * Stream info is not working yet
64
+ * Tests need to be written
65
+ * Needs to be turned into a gem
66
+
67
+
68
+ (c) 2010 Brandon Arbini / Zencoder, Inc.
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/testtask'
4
+
5
+ Rake::TestTask.new(:test) do |test|
6
+ test.libs << 'lib' << 'test'
7
+ test.pattern = 'test/**/*_test.rb'
8
+ test.verbose = true
9
+ end
10
+
11
+ task :default => :test
data/lib/m3uzi/file.rb ADDED
@@ -0,0 +1,9 @@
1
+ class M3Uzi
2
+
3
+ class File
4
+
5
+ attr_accessor :path, :duration, :description
6
+
7
+ end
8
+
9
+ end
@@ -0,0 +1,9 @@
1
+ class M3Uzi
2
+
3
+ class Stream
4
+
5
+ attr_accessor :bandwidth, :program_id, :codecs, :resolution
6
+
7
+ end
8
+
9
+ end
data/lib/m3uzi/tag.rb ADDED
@@ -0,0 +1,14 @@
1
+ class M3Uzi
2
+
3
+ class Tag
4
+
5
+ attr_reader :name
6
+ attr_accessor :value
7
+
8
+ def name=(n)
9
+ @name = n.to_s.upcase.sub("_", "-")
10
+ end
11
+
12
+ end
13
+
14
+ end
@@ -0,0 +1,3 @@
1
+ class M3Uzi
2
+ VERSION = '0.1.0'
3
+ end
data/lib/m3uzi.rb ADDED
@@ -0,0 +1,142 @@
1
+ $:<< File.dirname(__FILE__)
2
+ require 'm3uzi/tag'
3
+ require 'm3uzi/file'
4
+ require 'm3uzi/stream'
5
+ require 'm3uzi/version'
6
+
7
+ class M3Uzi
8
+
9
+ # Unsupported: KEY PROGRAM-DATE-TIME STREAM-INF DISCONTINUITY
10
+ VALID_TAGS = %w{TARGETDURATION MEDIA-SEQUENCE ALLOW-CACHE STREAM-INF ENDLIST VERSION}
11
+
12
+ attr_accessor :files
13
+ attr_accessor :tags
14
+
15
+ def initialize
16
+ @files = []
17
+ @tags = []
18
+ end
19
+
20
+
21
+ #-------------------------------------
22
+ # Read/Write M3U8 Files
23
+ #-------------------------------------
24
+
25
+ def self.read(path)
26
+ m3u = self.new
27
+ lines = ::File.readlines(path)
28
+ lines.each_with_index do |line, i|
29
+ case type(line)
30
+ when :tag
31
+ name, value = parse_general_tag(line)
32
+ m3u.add_tag do |tag|
33
+ tag.name = name
34
+ tag.value = value
35
+ end
36
+ when :info
37
+ duration, description = parse_file_tag(line)
38
+ m3u.add_file do |file|
39
+ file.path = lines[i+1].strip
40
+ file.duration = duration
41
+ file.description = description
42
+ end
43
+ else
44
+ next
45
+ end
46
+ end
47
+ m3u
48
+ end
49
+
50
+ def write(path)
51
+ f = ::File.open(path, "w")
52
+ f << "#EXTM3U\n"
53
+ tags.each do |tag|
54
+ next if %w{M3U ENDLIST}.include?(tag.name.to_s.upcase)
55
+ f << "#EXT-X-#{tag.name.to_s.upcase}"
56
+ tag.value && f << ":#{tag.value}"
57
+ f << "\n"
58
+ end
59
+ if !self[:targetduration]
60
+ f << "#EXT-X-TARGETDURATION:#{files.map(&:duration).sum}\n"
61
+ end
62
+ files.each do |file|
63
+ f << "#EXTINF:#{file.duration}"
64
+ file.description && f << ", #{file.description}"
65
+ f << "\n#{file.path}\n"
66
+ end
67
+ f << "#EXT-X-ENDLIST"
68
+ f.close()
69
+ end
70
+
71
+
72
+ #-------------------------------------
73
+ # Files
74
+ #-------------------------------------
75
+
76
+ def add_file(&block)
77
+ new_file = M3Uzi::File.new
78
+ yield(new_file)
79
+ @files << new_file
80
+ end
81
+
82
+ def filenames
83
+ files.map{|file| file.path }
84
+ end
85
+
86
+
87
+ #-------------------------------------
88
+ # Tags
89
+ #-------------------------------------
90
+
91
+ def add_tag(&block)
92
+ new_tag = M3Uzi::Tag.new
93
+ yield(new_tag)
94
+ @tags << new_tag
95
+ end
96
+
97
+ def [](key)
98
+ tag_name = key.to_s.upcase.sub("_", "-")
99
+ obj = tags.detect{|tag| tag.name == tag_name }
100
+ obj && obj.value
101
+ end
102
+
103
+ def []=(key, value)
104
+ add_tag do |tag|
105
+ tag.name = key
106
+ tag.value = value
107
+ end
108
+ end
109
+
110
+
111
+ protected
112
+
113
+ def self.type(line)
114
+ case line
115
+ when /^\s*$/
116
+ :whitespace
117
+ when /^#(?!EXT)/
118
+ :comment
119
+ when /^#EXTINF/
120
+ :info
121
+ when /^#EXT(?!INF)/
122
+ :tag
123
+ else
124
+ :file
125
+ end
126
+ end
127
+
128
+ def self.parse_general_tag(line)
129
+ line.match(/^#EXT(?:-X-)?(?!STREAM-INF)([^:\n]+)(:([^\n]+))?$/).values_at(1, 3)
130
+ end
131
+
132
+ def self.parse_file_tag(line)
133
+ line.match(/^#EXTINF:[ \t]*(\d+),?[ \t]*(.*)$/).values_at(1, 2)
134
+ end
135
+
136
+ def self.parse_stream_tag(line)
137
+ match = line.match(/^#EXT-X-STREAM-INF:(.*)$/)[1]
138
+ attributes = match.split(/\s*,\s*/)
139
+ attributes.map{|a| a.split(/\s*=\s*/) }
140
+ end
141
+
142
+ end
@@ -0,0 +1,366 @@
1
+ #EXTM3U
2
+ #EXT-X-TARGETDURATION:10
3
+ #EXT-X-MEDIA-SEQUENCE:0
4
+ #EXTINF:10, no desc
5
+ fileSequence0.ts
6
+ #EXTINF:10, no desc
7
+ fileSequence1.ts
8
+ #EXTINF:10, no desc
9
+ fileSequence2.ts
10
+ #EXTINF:10, no desc
11
+ fileSequence3.ts
12
+ #EXTINF:10, no desc
13
+ fileSequence4.ts
14
+ #EXTINF:10, no desc
15
+ fileSequence5.ts
16
+ #EXTINF:10, no desc
17
+ fileSequence6.ts
18
+ #EXTINF:10, no desc
19
+ fileSequence7.ts
20
+ #EXTINF:10, no desc
21
+ fileSequence8.ts
22
+ #EXTINF:10, no desc
23
+ fileSequence9.ts
24
+ #EXTINF:10, no desc
25
+ fileSequence10.ts
26
+ #EXTINF:10, no desc
27
+ fileSequence11.ts
28
+ #EXTINF:10, no desc
29
+ fileSequence12.ts
30
+ #EXTINF:10, no desc
31
+ fileSequence13.ts
32
+ #EXTINF:10, no desc
33
+ fileSequence14.ts
34
+ #EXTINF:10, no desc
35
+ fileSequence15.ts
36
+ #EXTINF:10, no desc
37
+ fileSequence16.ts
38
+ #EXTINF:10, no desc
39
+ fileSequence17.ts
40
+ #EXTINF:10, no desc
41
+ fileSequence18.ts
42
+ #EXTINF:10, no desc
43
+ fileSequence19.ts
44
+ #EXTINF:10, no desc
45
+ fileSequence20.ts
46
+ #EXTINF:10, no desc
47
+ fileSequence21.ts
48
+ #EXTINF:10, no desc
49
+ fileSequence22.ts
50
+ #EXTINF:10, no desc
51
+ fileSequence23.ts
52
+ #EXTINF:10, no desc
53
+ fileSequence24.ts
54
+ #EXTINF:10, no desc
55
+ fileSequence25.ts
56
+ #EXTINF:10, no desc
57
+ fileSequence26.ts
58
+ #EXTINF:10, no desc
59
+ fileSequence27.ts
60
+ #EXTINF:10, no desc
61
+ fileSequence28.ts
62
+ #EXTINF:10, no desc
63
+ fileSequence29.ts
64
+ #EXTINF:10, no desc
65
+ fileSequence30.ts
66
+ #EXTINF:10, no desc
67
+ fileSequence31.ts
68
+ #EXTINF:10, no desc
69
+ fileSequence32.ts
70
+ #EXTINF:10, no desc
71
+ fileSequence33.ts
72
+ #EXTINF:10, no desc
73
+ fileSequence34.ts
74
+ #EXTINF:10, no desc
75
+ fileSequence35.ts
76
+ #EXTINF:10, no desc
77
+ fileSequence36.ts
78
+ #EXTINF:10, no desc
79
+ fileSequence37.ts
80
+ #EXTINF:10, no desc
81
+ fileSequence38.ts
82
+ #EXTINF:10, no desc
83
+ fileSequence39.ts
84
+ #EXTINF:10, no desc
85
+ fileSequence40.ts
86
+ #EXTINF:10, no desc
87
+ fileSequence41.ts
88
+ #EXTINF:10, no desc
89
+ fileSequence42.ts
90
+ #EXTINF:10, no desc
91
+ fileSequence43.ts
92
+ #EXTINF:10, no desc
93
+ fileSequence44.ts
94
+ #EXTINF:10, no desc
95
+ fileSequence45.ts
96
+ #EXTINF:10, no desc
97
+ fileSequence46.ts
98
+ #EXTINF:10, no desc
99
+ fileSequence47.ts
100
+ #EXTINF:10, no desc
101
+ fileSequence48.ts
102
+ #EXTINF:10, no desc
103
+ fileSequence49.ts
104
+ #EXTINF:10, no desc
105
+ fileSequence50.ts
106
+ #EXTINF:10, no desc
107
+ fileSequence51.ts
108
+ #EXTINF:10, no desc
109
+ fileSequence52.ts
110
+ #EXTINF:10, no desc
111
+ fileSequence53.ts
112
+ #EXTINF:10, no desc
113
+ fileSequence54.ts
114
+ #EXTINF:10, no desc
115
+ fileSequence55.ts
116
+ #EXTINF:10, no desc
117
+ fileSequence56.ts
118
+ #EXTINF:10, no desc
119
+ fileSequence57.ts
120
+ #EXTINF:10, no desc
121
+ fileSequence58.ts
122
+ #EXTINF:10, no desc
123
+ fileSequence59.ts
124
+ #EXTINF:10, no desc
125
+ fileSequence60.ts
126
+ #EXTINF:10, no desc
127
+ fileSequence61.ts
128
+ #EXTINF:10, no desc
129
+ fileSequence62.ts
130
+ #EXTINF:10, no desc
131
+ fileSequence63.ts
132
+ #EXTINF:10, no desc
133
+ fileSequence64.ts
134
+ #EXTINF:10, no desc
135
+ fileSequence65.ts
136
+ #EXTINF:10, no desc
137
+ fileSequence66.ts
138
+ #EXTINF:10, no desc
139
+ fileSequence67.ts
140
+ #EXTINF:10, no desc
141
+ fileSequence68.ts
142
+ #EXTINF:10, no desc
143
+ fileSequence69.ts
144
+ #EXTINF:10, no desc
145
+ fileSequence70.ts
146
+ #EXTINF:10, no desc
147
+ fileSequence71.ts
148
+ #EXTINF:10, no desc
149
+ fileSequence72.ts
150
+ #EXTINF:10, no desc
151
+ fileSequence73.ts
152
+ #EXTINF:10, no desc
153
+ fileSequence74.ts
154
+ #EXTINF:10, no desc
155
+ fileSequence75.ts
156
+ #EXTINF:10, no desc
157
+ fileSequence76.ts
158
+ #EXTINF:10, no desc
159
+ fileSequence77.ts
160
+ #EXTINF:10, no desc
161
+ fileSequence78.ts
162
+ #EXTINF:10, no desc
163
+ fileSequence79.ts
164
+ #EXTINF:10, no desc
165
+ fileSequence80.ts
166
+ #EXTINF:10, no desc
167
+ fileSequence81.ts
168
+ #EXTINF:10, no desc
169
+ fileSequence82.ts
170
+ #EXTINF:10, no desc
171
+ fileSequence83.ts
172
+ #EXTINF:10, no desc
173
+ fileSequence84.ts
174
+ #EXTINF:10, no desc
175
+ fileSequence85.ts
176
+ #EXTINF:10, no desc
177
+ fileSequence86.ts
178
+ #EXTINF:10, no desc
179
+ fileSequence87.ts
180
+ #EXTINF:10, no desc
181
+ fileSequence88.ts
182
+ #EXTINF:10, no desc
183
+ fileSequence89.ts
184
+ #EXTINF:10, no desc
185
+ fileSequence90.ts
186
+ #EXTINF:10, no desc
187
+ fileSequence91.ts
188
+ #EXTINF:10, no desc
189
+ fileSequence92.ts
190
+ #EXTINF:10, no desc
191
+ fileSequence93.ts
192
+ #EXTINF:10, no desc
193
+ fileSequence94.ts
194
+ #EXTINF:10, no desc
195
+ fileSequence95.ts
196
+ #EXTINF:10, no desc
197
+ fileSequence96.ts
198
+ #EXTINF:10, no desc
199
+ fileSequence97.ts
200
+ #EXTINF:10, no desc
201
+ fileSequence98.ts
202
+ #EXTINF:10, no desc
203
+ fileSequence99.ts
204
+ #EXTINF:10, no desc
205
+ fileSequence100.ts
206
+ #EXTINF:10, no desc
207
+ fileSequence101.ts
208
+ #EXTINF:10, no desc
209
+ fileSequence102.ts
210
+ #EXTINF:10, no desc
211
+ fileSequence103.ts
212
+ #EXTINF:10, no desc
213
+ fileSequence104.ts
214
+ #EXTINF:10, no desc
215
+ fileSequence105.ts
216
+ #EXTINF:10, no desc
217
+ fileSequence106.ts
218
+ #EXTINF:10, no desc
219
+ fileSequence107.ts
220
+ #EXTINF:10, no desc
221
+ fileSequence108.ts
222
+ #EXTINF:10, no desc
223
+ fileSequence109.ts
224
+ #EXTINF:10, no desc
225
+ fileSequence110.ts
226
+ #EXTINF:10, no desc
227
+ fileSequence111.ts
228
+ #EXTINF:10, no desc
229
+ fileSequence112.ts
230
+ #EXTINF:10, no desc
231
+ fileSequence113.ts
232
+ #EXTINF:10, no desc
233
+ fileSequence114.ts
234
+ #EXTINF:10, no desc
235
+ fileSequence115.ts
236
+ #EXTINF:10, no desc
237
+ fileSequence116.ts
238
+ #EXTINF:10, no desc
239
+ fileSequence117.ts
240
+ #EXTINF:10, no desc
241
+ fileSequence118.ts
242
+ #EXTINF:10, no desc
243
+ fileSequence119.ts
244
+ #EXTINF:10, no desc
245
+ fileSequence120.ts
246
+ #EXTINF:10, no desc
247
+ fileSequence121.ts
248
+ #EXTINF:10, no desc
249
+ fileSequence122.ts
250
+ #EXTINF:10, no desc
251
+ fileSequence123.ts
252
+ #EXTINF:10, no desc
253
+ fileSequence124.ts
254
+ #EXTINF:10, no desc
255
+ fileSequence125.ts
256
+ #EXTINF:10, no desc
257
+ fileSequence126.ts
258
+ #EXTINF:10, no desc
259
+ fileSequence127.ts
260
+ #EXTINF:10, no desc
261
+ fileSequence128.ts
262
+ #EXTINF:10, no desc
263
+ fileSequence129.ts
264
+ #EXTINF:10, no desc
265
+ fileSequence130.ts
266
+ #EXTINF:10, no desc
267
+ fileSequence131.ts
268
+ #EXTINF:10, no desc
269
+ fileSequence132.ts
270
+ #EXTINF:10, no desc
271
+ fileSequence133.ts
272
+ #EXTINF:10, no desc
273
+ fileSequence134.ts
274
+ #EXTINF:10, no desc
275
+ fileSequence135.ts
276
+ #EXTINF:10, no desc
277
+ fileSequence136.ts
278
+ #EXTINF:10, no desc
279
+ fileSequence137.ts
280
+ #EXTINF:10, no desc
281
+ fileSequence138.ts
282
+ #EXTINF:10, no desc
283
+ fileSequence139.ts
284
+ #EXTINF:10, no desc
285
+ fileSequence140.ts
286
+ #EXTINF:10, no desc
287
+ fileSequence141.ts
288
+ #EXTINF:10, no desc
289
+ fileSequence142.ts
290
+ #EXTINF:10, no desc
291
+ fileSequence143.ts
292
+ #EXTINF:10, no desc
293
+ fileSequence144.ts
294
+ #EXTINF:10, no desc
295
+ fileSequence145.ts
296
+ #EXTINF:10, no desc
297
+ fileSequence146.ts
298
+ #EXTINF:10, no desc
299
+ fileSequence147.ts
300
+ #EXTINF:10, no desc
301
+ fileSequence148.ts
302
+ #EXTINF:10, no desc
303
+ fileSequence149.ts
304
+ #EXTINF:10, no desc
305
+ fileSequence150.ts
306
+ #EXTINF:10, no desc
307
+ fileSequence151.ts
308
+ #EXTINF:10, no desc
309
+ fileSequence152.ts
310
+ #EXTINF:10, no desc
311
+ fileSequence153.ts
312
+ #EXTINF:10, no desc
313
+ fileSequence154.ts
314
+ #EXTINF:10, no desc
315
+ fileSequence155.ts
316
+ #EXTINF:10, no desc
317
+ fileSequence156.ts
318
+ #EXTINF:10, no desc
319
+ fileSequence157.ts
320
+ #EXTINF:10, no desc
321
+ fileSequence158.ts
322
+ #EXTINF:10, no desc
323
+ fileSequence159.ts
324
+ #EXTINF:10, no desc
325
+ fileSequence160.ts
326
+ #EXTINF:10, no desc
327
+ fileSequence161.ts
328
+ #EXTINF:10, no desc
329
+ fileSequence162.ts
330
+ #EXTINF:10, no desc
331
+ fileSequence163.ts
332
+ #EXTINF:10, no desc
333
+ fileSequence164.ts
334
+ #EXTINF:10, no desc
335
+ fileSequence165.ts
336
+ #EXTINF:10, no desc
337
+ fileSequence166.ts
338
+ #EXTINF:10, no desc
339
+ fileSequence167.ts
340
+ #EXTINF:10, no desc
341
+ fileSequence168.ts
342
+ #EXTINF:10, no desc
343
+ fileSequence169.ts
344
+ #EXTINF:10, no desc
345
+ fileSequence170.ts
346
+ #EXTINF:10, no desc
347
+ fileSequence171.ts
348
+ #EXTINF:10, no desc
349
+ fileSequence172.ts
350
+ #EXTINF:10, no desc
351
+ fileSequence173.ts
352
+ #EXTINF:10, no desc
353
+ fileSequence174.ts
354
+ #EXTINF:10, no desc
355
+ fileSequence175.ts
356
+ #EXTINF:10, no desc
357
+ fileSequence176.ts
358
+ #EXTINF:10, no desc
359
+ fileSequence177.ts
360
+ #EXTINF:10, no desc
361
+ fileSequence178.ts
362
+ #EXTINF:10, no desc
363
+ fileSequence179.ts
364
+ #EXTINF:1, no desc
365
+ fileSequence180.ts
366
+ #EXT-X-ENDLIST
@@ -0,0 +1,9 @@
1
+ #EXTM3U
2
+ #EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=200000
3
+ gear1/prog_index.m3u8
4
+ #EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=311111
5
+ gear2/prog_index.m3u8
6
+ #EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=484444
7
+ gear3/prog_index.m3u8
8
+ #EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=737777
9
+ gear4/prog_index.m3u8
@@ -0,0 +1,18 @@
1
+ require 'rubygems'
2
+ require 'm3uzzi'
3
+ require 'test/unit'
4
+ require 'shoulda'
5
+
6
+ class M3UziTest < Test::Unit::TestCase
7
+
8
+ should "instantiate an M3Uzi object" do
9
+ m3u = M3Uzi.new
10
+ assert_equal M3Uzi, m3u.class
11
+ end
12
+
13
+ should "read in an index file" do
14
+ m3u = M3Uzi.read_file("#{Rails.root}/test/fixtures/index.m3u8")
15
+ assert_equal M3Uzi, m3u.class
16
+ end
17
+
18
+ end
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: m3uzi
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Brandon Arbini
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-08-27 00:00:00 -05:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: Read and write M3U files with (relative) ease.
23
+ email: brandon@zencoder.com
24
+ executables: []
25
+
26
+ extensions: []
27
+
28
+ extra_rdoc_files: []
29
+
30
+ files:
31
+ - lib/m3uzi/file.rb
32
+ - lib/m3uzi/stream.rb
33
+ - lib/m3uzi/tag.rb
34
+ - lib/m3uzi/version.rb
35
+ - lib/m3uzi.rb
36
+ - test/fixtures/index.m3u8
37
+ - test/fixtures/stream.m3u8
38
+ - test/m3uzzi_test.rb
39
+ - LICENSE
40
+ - Rakefile
41
+ - README.md
42
+ has_rdoc: true
43
+ homepage: http://github.com/zencoder/m3uzi
44
+ licenses: []
45
+
46
+ post_install_message:
47
+ rdoc_options: []
48
+
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ hash: 3
57
+ segments:
58
+ - 0
59
+ version: "0"
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ hash: 3
66
+ segments:
67
+ - 0
68
+ version: "0"
69
+ requirements: []
70
+
71
+ rubyforge_project:
72
+ rubygems_version: 1.3.7
73
+ signing_key:
74
+ specification_version: 3
75
+ summary: Read and write M3U files with (relative) ease.
76
+ test_files: []
77
+