ariblib 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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(){