ariblib 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,184 @@
1
+ #!ruby
2
+ # -*- encoding: utf-8 -*-
3
+
4
+ module Ariblib
5
+
6
+ #番組表テーブル
7
+ class EventInformationTable < ProgramSpecificInformation #< 4Kbyte super(x,y)
8
+
9
+
10
+ class SelfWeeklyMultiEventSchedule
11
+ def initialize
12
+ refresh
13
+ end
14
+ def refresh
15
+ @table=[]
16
+ @start=nil
17
+ @end=nil
18
+ @cur=nil
19
+ end
20
+ def finish
21
+ end
22
+ def inc
23
+ while @cur < @table.size
24
+ cur =@table[@cur ][2]
25
+ nxt =@table[@cur+1][1]
26
+ @cur+=1 if cur==nxt
27
+ end
28
+ end
29
+ def binary_insert(a,e)
30
+ if a.size > 0
31
+ index = [*a.each_with_index].bsearch{|x, _| x[1] > e[1]}.last
32
+ a.insert(index, e) if a[index][1]!=e[1]
33
+ while a[@cur][2]==a[@cur+1][1]
34
+ @cur+=1
35
+ end
36
+ else
37
+ a.insert(0, e)
38
+ @cur=0
39
+ end
40
+ end
41
+ def check(uid,tid,last_tid,seg_last,list)
42
+ if tid ==0x4e00 && list.size >0#自ストリーム現在地
43
+ unless @cur
44
+ tmp=list[0][1]
45
+ @cur=0 if @table.bsearch{|v|v[1]>=tmp}
46
+ end
47
+ elsif tid < 0x5000 #他ストリームnext
48
+ elsif tid < 0x5200 #自ストリームtable 0x1ff -> 3f
49
+ @end=list.last if @end==nil and tid==last_tid #and list.size >0
50
+ tmp=@table && @start[2]
51
+ list.each do |v|
52
+ next unless v[3][:title]
53
+ @table << v
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+
60
+ class SelfWeeklyMultiSchedule
61
+ def initialize
62
+ refresh
63
+ end
64
+ #8[bit/seg]*8[seg/day]*8[day]=512[bit]=64byte=16word
65
+ #512[bit]/8[day]=64[bit/day]
66
+ #64[bit/day]/8[seg/day]=8[bit/seg]
67
+ def refresh
68
+ @table=Hash.new(){|k,v|k[v]=[Array.new(512/8,0),false]}
69
+ end
70
+ def finish
71
+ return false if table.size==0
72
+ @table.values.inject(true){|ret,v|ret && v[1]}
73
+ end
74
+
75
+ def check(uid,tid,last_tid,seg_last,list)
76
+ #if tid < 0x4800 #違法
77
+ if tid ==0x4e00 && list.size >0#自ストリーム現在地
78
+ seg=@table[uid][0]
79
+ #過去セグメントを埋める。
80
+ hour=list[0][1].hour
81
+ #p 'uid=%08x tid=%04x,last=%02x,hour=%02x' % [uid,tid,seg_last,hour]
82
+ (hour/3).floor.times{|v|seg[v]=0xff}
83
+ #elsif tid <0x4900 #自ストリームnext
84
+ #elsif tid ==0x4900 #他ストリーム現在地
85
+ elsif tid < 0x5000 #他ストリームnext
86
+ elsif tid < 0x5200 #自ストリームtable 0x1ff -> 3f
87
+ ind=(tid-0x5000)>>3
88
+ seg=@table[uid][0]
89
+ tmp =seg[ind]
90
+ if tmp !=0xff
91
+ tmp4=((tid&0x00ff)==seg_last)?0xff : 1
92
+ tmp5=tmp | ((tmp4<<(tid&0x0007))&0xff)
93
+ seg[ind]=tmp5
94
+ if tmp5==0xff
95
+ t=seg[0,512/8].inject{|x,y|x&y}
96
+ @table[uid][1]=true if t==0xff
97
+ end
98
+ end
99
+ #elsif tid <0x6000 #自ストリーム詳細
100
+ #elsif tid <0x7000 #他ストリームtable
101
+ else #違法
102
+ end
103
+ end
104
+ end
105
+
106
+
107
+ def initialize
108
+ super
109
+ @schedule=SelfWeeklyMultiSchedule.new
110
+ end
111
+ attr_reader :schedule
112
+ def parse_buf
113
+ ret=[]
114
+ bs=BitStream.new(@buf)
115
+ #event_information_section(){
116
+ table_id =bs.getc #8 uimsbf
117
+ #staff_table if table_id == 0x72
118
+ tmp =bs.gets
119
+ section_length =tmp & 0x0fff
120
+ #section_syntax_indicator =bs.read 1 #bslbf
121
+ #reserved_future_use =bs.read 1 #bslbf
122
+ #reserved =bs.read 2 #bslbf
123
+ #section_length =bs.read 12 # < 4096 -3
124
+ service_id =bs.gets #16 uimsbf
125
+ tmp =bs.getc
126
+ #reserved =bs.read 2 #bslbf
127
+ #version_number =bs.read 5 #uimsbf
128
+ #current_next_indicator =bs.read 1 #bslbf
129
+ section_number =bs.getc #8 uimsbf
130
+ last_section_number =bs.getc #8 uimsbf
131
+ transport_stream_id =bs.gets #16 uimsbf
132
+ original_network_id =bs.gets #16 uimsbf
133
+ segment_last_section_number =bs.getc #8 uimsbf
134
+ last_table_id =bs.getc #8 uimsbf
135
+
136
+ uid=(original_network_id<<(16+16))|(transport_stream_id<<(16))|service_id
137
+ tid =( table_id<<8)| section_number
138
+ last_tid=(last_table_id<<8)|last_section_number
139
+
140
+ len=(section_length+3-4)*8
141
+ while bs.pos < len
142
+ event_id =bs.gets #16 #uimsbf
143
+ start_mdj =bs.gets #16 #bslbf
144
+ start_time =bs.get3 #24 #bslbf
145
+ duration =bs.get3 #24 #uimsbf
146
+ tmp =bs.gets
147
+ #running_status =bs.read 3 #uimsbf
148
+ #free_CA_mode =bs.read 1 #bslbf
149
+ #descriptors_loop_length =bs.read 12 #uimsbf
150
+ desc = descriptor(bs,tmp & 0x0fff)
151
+
152
+ start=Date.jd(start_mdj+2400001).to_datetime + time_to_datetime(start_time)
153
+ fin =start+time_to_datetime(duration)
154
+ @contents << [uid,tid,event_id,start,fin,desc]
155
+ #ret << ' %04x|%s|%s' % [event_id,start.strftime('%Y%m%d%H%M'),fin.strftime('%Y%m%d%H%M')]
156
+ end
157
+ cCRC_32 =bs.read 32 #rpchof
158
+
159
+ #@schedule.check(uid,tid,last_tid,segment_last_section_number,ret)
160
+ #tmp= [table_id,transport_stream_id,original_network_id,service_id,section_number,last_section_number,segment_last_section_number,last_table_id,ret.size]
161
+ #ret.unshift("tid=%02x,tpid=%04x,nid=%04x,serid=%04x,secnum=%02x,lastsec=%02x,seglast=%02x,ltid=%02x,n=%d" % tmp)
162
+ #@debug||=Hash.new(){|k,v|k[v]={}}
163
+ #tmp=@debug[uid][tid]
164
+ #@debug[uid][tid] = ret
165
+ #@debug[uid]=@debug[uid].sort_by{|k,v| k}.to_h unless tmp
166
+ nil
167
+ end
168
+ def time_to_datetime(t)
169
+ sec =(t & 0x0000000f)
170
+ t>>=4
171
+ sec+=(t & 0x0000000f)*10
172
+ t>>=4
173
+ sec+=(t & 0x0000000f)*60
174
+ t>>=4
175
+ sec+=(t & 0x0000000f)*600
176
+ t>>=4
177
+ sec+=(t & 0x0000000f)*3600
178
+ t>>=4
179
+ sec+=(t & 0x0000000f)*36000
180
+ Rational(sec,24*60*60)
181
+ end
182
+ end
183
+ end
184
+ __END__
@@ -0,0 +1,318 @@
1
+ #!ruby
2
+ # -*- encoding: utf-8 -*-
3
+ require 'date'
4
+
5
+ module Ariblib
6
+
7
+ #PSI TSペイロード
8
+ class ProgramSpecificInformation
9
+ def initialize
10
+ @buf=''.force_encoding('ASCII-8BIT')
11
+ @count=nil
12
+ @length=nil
13
+ @contents=[]
14
+ @descriptor_set=DescriptorTag
15
+ end
16
+ def init_buf
17
+ @buf.clear
18
+ @length=nil
19
+ end
20
+
21
+ def set_buf(ts,buf)
22
+ return unless @count
23
+ @buf+=buf
24
+ @length=(((@buf.getbyte(1)<<8) | @buf.getbyte(2))&0x0fff)+3 if (@length==nil) && (@buf.length>=3)
25
+ if @buf.length>=@length
26
+ @ts=ts
27
+ tmp =parse_buf
28
+ @contents << tmp if tmp
29
+ @count=nil
30
+ else
31
+ @count=(@count+1)&0x0f
32
+ end
33
+ end
34
+
35
+ def set(ts)
36
+ @count=nil if ts.continuity_counter != @count
37
+ buf=ts.bs.str(ts.payload_length)
38
+
39
+ if ts.payload_unit_start_indicator != 0
40
+ set_buf(ts,buf.byteslice(1,188))
41
+
42
+ @count=ts.continuity_counter
43
+ init_buf
44
+ set_buf(ts,buf.byteslice(buf.getbyte(0)+1,188))
45
+ else
46
+ set_buf(ts,buf)
47
+ end
48
+ end
49
+
50
+ def arib_to_utf8(buf)
51
+ Ariblib::String.new(Ariblib::BitStream.new(buf),buf.length).to_utf8
52
+ end
53
+ def descriptor(bs,len)
54
+ return nil if len==0
55
+ h={:tag => [],
56
+ :verbose_pair=>[],
57
+ :verbose=>''.force_encoding('ASCII-8BIT'),
58
+ }
59
+
60
+ len=bs.pos+len*8
61
+ while bs.pos < len
62
+ descriptor_tag =bs.getc #8 uimsbf
63
+ descriptor_length =bs.getc #8 uimsbf
64
+ len2=bs.pos+descriptor_length*8
65
+ @descriptor_set[descriptor_tag].new(h,bs,descriptor_tag,descriptor_length)
66
+ bs.pos=len2
67
+ end
68
+ bs.pos=len
69
+ h[:verbose_pair]=h[:verbose_pair].map{|v|[v[0],arib_to_utf8(v[1])]}
70
+ h[:verbose]=arib_to_utf8(h[:verbose])
71
+ h.delete :verbose_pair if h[:verbose_pair].size==0
72
+ h.delete :verbose if h[:verbose].size==0
73
+ h
74
+ end
75
+ attr_reader :contents
76
+ end
77
+ class ServiceDescriptionTable < ProgramSpecificInformation #< 1Kbyte
78
+ def parse_buf
79
+ ret=[]
80
+ bs=BitStream.new(@buf)
81
+ #service_description_section(){
82
+ table_id =bs.read 8 #uimsbf
83
+ #staff_table if table_id == 0x72
84
+ section_syntax_indicator =bs.read 1 #bslbf
85
+ reserved_future_use =bs.read 1 #bslbf
86
+ reserved =bs.read 2 #bslbf
87
+ section_length =bs.read 12 #uimsbf# < 1024 -3
88
+ transport_stream_id =bs.read 16 #uimsbf
89
+ reserved =bs.read 2 #bslbf
90
+ version_number =bs.read 5 #uimsbf
91
+ current_next_indicator =bs.read 1 #bslbf
92
+ section_number =bs.read 8 #uimsbf
93
+ last_section_number =bs.read 8 #uimsbf
94
+ original_network_id =bs.read 16 #uimsbf
95
+ reserved_future_use =bs.read 8 #bslbf
96
+ ret << [table_id,original_network_id,transport_stream_id]
97
+ len=(section_length+3-4)*8
98
+ while bs.pos < len
99
+ service_id =bs.read 16 #uimsbf
100
+ reserved_future_use =bs.read 3 #bslbf
101
+ fEIT_user_defined_flags =bs.read 3 #bslbf
102
+ fEIT_schedule_flag =bs.read 1 #bslbf
103
+ fEIT_present_following_flag =bs.read 1 #bslbf
104
+ running_status =bs.read 3 #uimsbf
105
+ free_CA_mode =bs.read 1 #bslbf
106
+ descriptors_loop_length =bs.read 12 #uimsbf
107
+ desc=descriptor(bs,descriptors_loop_length)
108
+ ret << [service_id,desc]
109
+ end
110
+ cCRC_32 =bs.read 32 #rpchof
111
+ ret
112
+ end
113
+ end
114
+ class ProgramAssociationTable < ProgramSpecificInformation #< 1Kbyte
115
+ def parse_buf
116
+ bs=BitStream.new(@buf)
117
+ table_id =bs.read 8 #uimsbf
118
+ section_syntax_indicator =bs.read 1 #bslbf
119
+ reserved_future_use =bs.read 1 #bslbf
120
+ reserved =bs.read 2 #bslbf
121
+ section_length =bs.read 12 #uimsbf
122
+ transport_stream_id =bs.read 16 #uimsbf
123
+ reserved =bs.read 2 #bslbf
124
+ version_number =bs.read 5 #uimsbf
125
+ current_next_indicator =bs.read 1 #bslbf
126
+ section_number =bs.read 8 #uimsbf
127
+ last_section_number =bs.read 8 #uimsbf
128
+ count=(section_length-5-4)/4
129
+ count.times do
130
+ program_number =bs.read 16 #uimsbf
131
+ reserved =bs.read 3 #bslbf
132
+ if(program_number == 0)
133
+ network_PID =bs.read 13 #uimsbf
134
+ else
135
+ program_map_PID =bs.read 13 #uimsbf
136
+ end
137
+ end
138
+ cCRC_32 =bs.read 32 #rpchof
139
+ nil
140
+ end
141
+ end
142
+ class ProgramMapTable < ProgramSpecificInformation #< 1Kbyte
143
+ def parse_buf
144
+ #TS_program_map_section()
145
+ bs=BitStream.new(@buf)
146
+ table_id =bs.read 8 #uimsbf
147
+ section_syntax_indicator =bs.read 1 #bslbf
148
+ reserved_future_use =bs.read 1 #bslbf
149
+ reserved =bs.read 2 #bslbf
150
+ section_length =bs.read 12 #uimsbf
151
+ len=section_length*8+bs.pos-32
152
+ program_number =bs.read 16 #uimsbf
153
+ reserved =bs.read 2 #bslbf
154
+ version_number =bs.read 5 #uimsbf
155
+ current_next_indicator =bs.read 1 #bslbf
156
+ section_number =bs.read 8 #uimsbf
157
+ last_section_number =bs.read 8 #uimsbf
158
+ reserved =bs.read 3 #bslbf
159
+ iPCR_PID =bs.read 13 #uimsbf
160
+ reserved =bs.read 4 #bslbf
161
+ program_info_length =bs.read 12 #uimsbf
162
+ descriptor(bs,program_info_length)
163
+
164
+ while(bs.pos < len)
165
+ stream_type =bs.read 8 #uimsbf
166
+ reserved =bs.read 3 #bslbf
167
+ elementary_PID =bs.read 13 #uimsnf
168
+ reserved =bs.read 4 #bslbf
169
+ es_info_length =bs.read 12 #uimsbf
170
+ descriptor(bs,es_info_length)
171
+ end
172
+ cCRC_32 =bs.read 32 #rpchof
173
+ nil
174
+ end
175
+ end
176
+ class ConditionalAccessTable < ProgramSpecificInformation #< 1Kbyte
177
+ def parse_buf
178
+ bs=BitStream.new(@buf)
179
+ table_id =bs.read 8 #uimsbf
180
+ section_syntax_indicator =bs.read 1 #bslbf
181
+ reserved_future_use =bs.read 1 #bslbf
182
+ reserved =bs.read 2 #bslbf
183
+ section_length =bs.read 12 #uimsbf
184
+ reserved =bs.read 18 #bslbf
185
+ version_number =bs.read 5 #uimsbf
186
+ current_next_indicator =bs.read 1 #bslbf
187
+ section_number =bs.read 8 #uimsbf
188
+ last_section_number =bs.read 8 #uimsbf
189
+ count=section_length-9
190
+ descriptor(bs,count)
191
+ cCRC_32 =bs.read 32 #rpchof
192
+ nil
193
+ end
194
+ end
195
+ class NetworkInformationTable < ProgramSpecificInformation #< 1Kbyte
196
+ def parse_buf
197
+ ret=[]
198
+ bs=BitStream.new(@buf)
199
+ table_id =bs.read 8 #uimsbf
200
+ section_syntax_indicator =bs.read 1 #bslbf
201
+ reserved_future_use =bs.read 1 #bslbf
202
+ reserved =bs.read 2 #bslbf
203
+ section_length =bs.read 12 #uimsbf
204
+ network_id =bs.read 16 #uimsbf
205
+ reserved =bs.read 2 #bslbf
206
+ version_number =bs.read 5 #uimsbf
207
+ current_next_indicator =bs.read 1 #bslbf
208
+ section_number =bs.read 8 #uimsbf
209
+ last_section_number =bs.read 8 #uimsbf
210
+ reserved_future_use =bs.read 4 #bslbf
211
+ network_descriptors_length =bs.read 12 #uimsbf
212
+ desc=descriptor(bs,network_descriptors_length)
213
+ ret << [:NIT,table_id,desc]
214
+ reserved_future_use =bs.read 4 #bslbf
215
+ transport_stream_loop_length =bs.read 12 #uimsbf
216
+
217
+ len=bs.pos+transport_stream_loop_length*8
218
+ while bs.pos < len
219
+ transport_stream_id =bs.read 16 #uimsbf
220
+ original_network_id =bs.read 16 #uimsbf
221
+ reserved_future_use =bs.read 4 #bslbf
222
+ transport_descriptors_length =bs.read 12 #uimsbf
223
+ desc=descriptor(bs,transport_descriptors_length)
224
+ ret << [transport_stream_id,original_network_id,desc]
225
+ end
226
+ cCRC_32 =bs.read 32 #rpchof
227
+ ret
228
+ end
229
+ end
230
+ class TimeOffsetTable < ProgramSpecificInformation #< 1Kbyte
231
+ def parse_buf
232
+ ret=nil
233
+ bs=BitStream.new(@buf)
234
+ table_id =bs.read 8 #uimsbf
235
+ section_syntax_indicator =bs.read 1 #bslbf
236
+ reserved_future_use =bs.read 1 #bslbf
237
+ reserved =bs.read 2 #bslbf
238
+ section_length =bs.read 12 #uimsbf
239
+ jst_time =bs.read 40 #bslbf
240
+ if table_id == 0x73
241
+ reserved =bs.read 4 #bslbf
242
+ descriptors_loop_length =bs.read 12 #uimsbf
243
+ desc=descriptor(bs,descriptors_loop_length)
244
+ ret=[jst_time,desc]
245
+ else
246
+ ret=[jst_time]
247
+ end
248
+ cCRC_32 =bs.read 32 #rpchof
249
+ ret
250
+ end
251
+ def to_datetime(n=0)
252
+ dat=@contents[n]
253
+ return nil unless dat
254
+ jst=dat[0]
255
+ sec1 =(jst>> 0)&0x0f
256
+ sec10 =(jst>> 4)&0x0f
257
+ min1 =(jst>> 8)&0x0f
258
+ min10 =(jst>>12)&0x0f
259
+ hour1 =(jst>>16)&0x0f
260
+ hour10=(jst>>20)&0x0f
261
+ mjd =(jst>>24)+2400001
262
+ return DateTime.jd(mjd,hour10*10+hour1,min10*10+min1,sec10*10+sec1)#+Rational(1,24*60)
263
+ end
264
+ end
265
+ class CommonDataTable < ProgramSpecificInformation #< 1Kbyte
266
+ def parse_buf
267
+ ret=nil
268
+ bs=BitStream.new(@buf)
269
+ table_id =bs.read 8 #uimsbf
270
+ section_syntax_indicator =bs.read 1 #bslbf
271
+ reserved_future_use =bs.read 1 #bslbf
272
+ reserved =bs.read 2 #bslbf
273
+ section_length =bs.read 12 #uimsbf
274
+
275
+ download_data_id =bs.read 16 #uimsbf
276
+ reserved =bs.read 2 #bslbf
277
+ version_number =bs.read 5 #uimsbf
278
+ current_next_indicator =bs.read 1 #bslbf
279
+ section_number =bs.read 8 #uimsbf
280
+ last_section_number =bs.read 8 #uimsbf
281
+ original_network_id =bs.read 16 #uimsbf
282
+ data_type =bs.read 8 #uimsbf =0x01
283
+ reserved_future_use =bs.read 4 #bslbf
284
+ descriptors_loop_length =bs.read 12 #uimsbf
285
+ desc=descriptor(bs,descriptors_loop_length)
286
+
287
+ ret = 'ddid=%04x vid=%02x onid=%04x type=%02x' % [
288
+ download_data_id,
289
+ version_number,
290
+ original_network_id,
291
+ data_type]
292
+
293
+ if data_type == 0x01
294
+ logo_type =bs.read 8 #uimsbf
295
+ reserved_future_use =bs.read 7 #bslbf
296
+ logo_id =bs.read 9 #uimsbf
297
+ reserved_future_use =bs.read 4 #bslbf
298
+ logo_version =bs.read 12 #uimsbf
299
+ data_size =bs.read 16 #uimsbf
300
+ data_byte =bs.str data_size
301
+ ret = ['ddid=%04x vid=%02x onid=%04x type=%02x loid=%02x lver=%03x dt=%s' % [
302
+ download_data_id,
303
+ version_number,
304
+ original_network_id,
305
+ logo_type,logo_id,logo_version,data_byte],desc]
306
+
307
+ else
308
+ len=(section_length+3)-10-descriptors_loop_length-4
309
+ data_module_byte =bs.str len
310
+ end
311
+
312
+ cCRC_32 =bs.read 32 #rpchof
313
+ ret
314
+ end
315
+ end
316
+ end
317
+ __END__
318
+ data_module_byte(){