tsparser 0.0.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.
- checksums.yaml +7 -0
- data/LICENSE +20 -0
- data/README.rdoc +16 -0
- data/lib/arib_string_decoder.rb +441 -0
- data/lib/binary.rb +202 -0
- data/lib/definition/arib_duration.rb +19 -0
- data/lib/definition/arib_string.rb +327 -0
- data/lib/definition/arib_time.rb +41 -0
- data/lib/definition/descriptor.rb +27 -0
- data/lib/definition/descriptor/audio_component_descriptor.rb +12 -0
- data/lib/definition/descriptor/ca_contract_information_descriptor.rb +12 -0
- data/lib/definition/descriptor/component_descriptor.rb +18 -0
- data/lib/definition/descriptor/content_descriptor.rb +37 -0
- data/lib/definition/descriptor/data_content_descriptor.rb +12 -0
- data/lib/definition/descriptor/digital_copy_control_descriptor.rb +12 -0
- data/lib/definition/descriptor/event_group_descriptor.rb +12 -0
- data/lib/definition/descriptor/extended_event_descriptor.rb +52 -0
- data/lib/definition/descriptor/short_event_descriptor.rb +17 -0
- data/lib/definition/descriptor/unknown_descriptor.rb +13 -0
- data/lib/definition/descriptor_list.rb +17 -0
- data/lib/definition/eit_event.rb +21 -0
- data/lib/definition/event_information_section.rb +53 -0
- data/lib/definition/event_list.rb +17 -0
- data/lib/definition/transport_packet.rb +68 -0
- data/lib/epg.rb +29 -0
- data/lib/parsing.rb +63 -0
- data/lib/psi_section_reader.rb +39 -0
- data/lib/ts.rb +41 -0
- data/lib/tsparser.rb +75 -0
- metadata +72 -0
data/lib/epg.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module TSparser
|
3
|
+
class EPG
|
4
|
+
include Enumerable
|
5
|
+
|
6
|
+
def initialize(epg_hash=Hash.new)
|
7
|
+
@epg = epg_hash
|
8
|
+
end
|
9
|
+
|
10
|
+
def add(event_id, attr_hash)
|
11
|
+
@epg[event_id] = attr_hash
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_reader :epg
|
15
|
+
|
16
|
+
def +(other)
|
17
|
+
new_hash = @epg.merge(other.epg) do |event_id, attr_hash1, attr_hash2|
|
18
|
+
attr_hash1.merge(attr_hash2) do |attr_name, val1, val2|
|
19
|
+
[val1, val2].max{|a, b| a.to_s.size <=> b.to_s.size}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
return EPG.new(new_hash)
|
23
|
+
end
|
24
|
+
|
25
|
+
def each(&block)
|
26
|
+
@epg.each_value(&block)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/parsing.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module TSparser
|
3
|
+
module Parsing
|
4
|
+
|
5
|
+
def initialize(binary, parsing_proc=nil, delay=true)
|
6
|
+
@binary = binary
|
7
|
+
@parsed_variable = Hash.new
|
8
|
+
if delay
|
9
|
+
@parsing_proc = parsing_proc
|
10
|
+
else
|
11
|
+
self.instance_eval(&parsing_proc) if parsing_proc
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def read(name, type, bit)
|
16
|
+
if type == Integer
|
17
|
+
val = @binary.read_bit_as_integer(bit)
|
18
|
+
@parsed_variable[name] = val
|
19
|
+
else
|
20
|
+
val = @binary.read_bit_as_binary(bit)
|
21
|
+
@parsed_variable[name] = Proc.new{ type.new(val) }
|
22
|
+
end
|
23
|
+
rescue => error
|
24
|
+
STDERR.puts "Parsing error occurred at class: #{self.class}, attr: #{name}(type:#{type}, bitlen:#{bit})"
|
25
|
+
raise error
|
26
|
+
end
|
27
|
+
|
28
|
+
def rest_all
|
29
|
+
return @binary.rest_readable_bit_length
|
30
|
+
end
|
31
|
+
|
32
|
+
def method_missing(name, *args)
|
33
|
+
if @parsing_proc
|
34
|
+
parsing_proc = @parsing_proc
|
35
|
+
@parsing_proc = nil
|
36
|
+
self.instance_eval(&parsing_proc)
|
37
|
+
end
|
38
|
+
if @parsed_variable[name]
|
39
|
+
if @parsed_variable[name].instance_of?(Proc)
|
40
|
+
@parsed_variable[name] = @parsed_variable[name].call
|
41
|
+
end
|
42
|
+
return @parsed_variable[name]
|
43
|
+
end
|
44
|
+
super
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.included(klass)
|
48
|
+
klass.extend ClassExtension
|
49
|
+
end
|
50
|
+
|
51
|
+
module ClassExtension
|
52
|
+
|
53
|
+
def def_parsing(delay=true, &block)
|
54
|
+
@delay = delay
|
55
|
+
@parsing_definition = block
|
56
|
+
end
|
57
|
+
|
58
|
+
def new(binary)
|
59
|
+
super(binary, @parsing_definition, @delay)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module TSparser
|
3
|
+
class PSISectionReader
|
4
|
+
|
5
|
+
def initialize(pid, ts)
|
6
|
+
@ts = ts.filter(pid)
|
7
|
+
end
|
8
|
+
|
9
|
+
def read
|
10
|
+
cont_packets = []
|
11
|
+
while packet = @ts.read
|
12
|
+
if packet.payload_unit_start_indicator == 1
|
13
|
+
if @start_packet && continuity_check(@start_packet, *cont_packets, packet)
|
14
|
+
binary = @start_packet.payload.from(@start_packet.payload.b(0) + 1)
|
15
|
+
binary = binary.join(*cont_packets.map{|packet| packet.payload})
|
16
|
+
@start_packet = packet
|
17
|
+
return binary
|
18
|
+
else
|
19
|
+
@start_packet = packet
|
20
|
+
cont_packets = []
|
21
|
+
next
|
22
|
+
end
|
23
|
+
end
|
24
|
+
cont_packets << packet
|
25
|
+
end
|
26
|
+
return nil
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def continuity_check(first_packet, *packets)
|
32
|
+
counter = first_packet.continuity_counter
|
33
|
+
return packets.all? do |packet|
|
34
|
+
counter += 1
|
35
|
+
packet.continuity_counter == counter % 16
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/ts.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module TSparser
|
3
|
+
class TS
|
4
|
+
|
5
|
+
def initialize(io, filtering_procs=[])
|
6
|
+
@io = io
|
7
|
+
@filtering_procs = filtering_procs
|
8
|
+
end
|
9
|
+
|
10
|
+
def filter(*pids, &block)
|
11
|
+
new_filtering_procs = @filtering_procs
|
12
|
+
if pids.length > 0
|
13
|
+
new_filtering_procs = [Proc.new{|packet| pids.include?(packet.pid)}] + new_filtering_procs
|
14
|
+
end
|
15
|
+
if block
|
16
|
+
new_filtering_procs = new_filtering_procs + [block]
|
17
|
+
end
|
18
|
+
return TS.new(@io, new_filtering_procs)
|
19
|
+
end
|
20
|
+
|
21
|
+
def read
|
22
|
+
loop do
|
23
|
+
return nil if eof?
|
24
|
+
packet_binary = Binary.new(@io.read(188))
|
25
|
+
if packet_binary.length != 188
|
26
|
+
raise "Bytes less than 188byte (#{packet_bytes.length}byte) were read from TS file."
|
27
|
+
end
|
28
|
+
packet = TransportPacket.new(packet_binary)
|
29
|
+
return packet if @filtering_procs.all?{|filter| filter.call(packet)}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def eof?
|
34
|
+
return @io.eof?
|
35
|
+
end
|
36
|
+
|
37
|
+
def close
|
38
|
+
@io.close
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/tsparser.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module TSparser
|
3
|
+
extend self
|
4
|
+
|
5
|
+
LIBRARY_ROOT_PATH = File.expand_path(File.dirname(__FILE__))
|
6
|
+
|
7
|
+
MAIN_FILES =
|
8
|
+
['/binary.rb',
|
9
|
+
'/parsing.rb',
|
10
|
+
'/ts.rb',
|
11
|
+
'/psi_section_reader.rb',
|
12
|
+
'/arib_string_decoder.rb',
|
13
|
+
'/epg.rb'
|
14
|
+
]
|
15
|
+
|
16
|
+
|
17
|
+
DEFINITION_DESCRIPTOR_FILES =
|
18
|
+
['/short_event_descriptor.rb',
|
19
|
+
'/extended_event_descriptor.rb',
|
20
|
+
'/component_descriptor.rb',
|
21
|
+
'/content_descriptor.rb',
|
22
|
+
'/digital_copy_control_descriptor.rb',
|
23
|
+
'/audio_component_descriptor.rb',
|
24
|
+
'/data_content_descriptor.rb',
|
25
|
+
'/ca_contract_information_descriptor.rb',
|
26
|
+
'/event_group_descriptor.rb',
|
27
|
+
'/unknown_descriptor.rb'
|
28
|
+
]
|
29
|
+
|
30
|
+
DEFINITION_FILES =
|
31
|
+
['/descriptor.rb',
|
32
|
+
'/descriptor_list.rb',
|
33
|
+
'/eit_event.rb',
|
34
|
+
'/event_information_section.rb',
|
35
|
+
'/event_list.rb',
|
36
|
+
'/transport_packet.rb',
|
37
|
+
'/arib_duration.rb',
|
38
|
+
'/arib_time.rb',
|
39
|
+
'/arib_string.rb'
|
40
|
+
]
|
41
|
+
|
42
|
+
MAIN_FILES.each do |path|
|
43
|
+
require LIBRARY_ROOT_PATH + path
|
44
|
+
end
|
45
|
+
|
46
|
+
DEFINITION_DESCRIPTOR_FILES.each do |path|
|
47
|
+
require LIBRARY_ROOT_PATH + '/definition/descriptor' + path
|
48
|
+
end
|
49
|
+
|
50
|
+
DEFINITION_FILES.each do |path|
|
51
|
+
require LIBRARY_ROOT_PATH + '/definition' + path
|
52
|
+
end
|
53
|
+
|
54
|
+
def parse_epg(input)
|
55
|
+
epg = EPG.new
|
56
|
+
section_stream = PSISectionReader.new(0x12, open_ts(input))
|
57
|
+
while section_binary = section_stream.read
|
58
|
+
next unless EventInformationSection.section_length_enough?(section_binary)
|
59
|
+
eis = EventInformationSection.new(section_binary)
|
60
|
+
epg = epg + eis.to_epg
|
61
|
+
end
|
62
|
+
return epg
|
63
|
+
end
|
64
|
+
|
65
|
+
def open_ts(input)
|
66
|
+
case input
|
67
|
+
when String
|
68
|
+
return TS.new(File.open(input, "rb"))
|
69
|
+
when IO
|
70
|
+
return TS.new(input)
|
71
|
+
else
|
72
|
+
raise "arugument should be TS file path(String) or IO"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
metadata
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tsparser
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- rokugatsu
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-01-02 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: |2
|
14
|
+
This is a general-purpose MPEG-TS parser.
|
15
|
+
email: sasasawada@gmail.com
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- lib/arib_string_decoder.rb
|
21
|
+
- lib/binary.rb
|
22
|
+
- lib/definition/arib_duration.rb
|
23
|
+
- lib/definition/arib_string.rb
|
24
|
+
- lib/definition/arib_time.rb
|
25
|
+
- lib/definition/descriptor.rb
|
26
|
+
- lib/definition/descriptor/audio_component_descriptor.rb
|
27
|
+
- lib/definition/descriptor/ca_contract_information_descriptor.rb
|
28
|
+
- lib/definition/descriptor/component_descriptor.rb
|
29
|
+
- lib/definition/descriptor/content_descriptor.rb
|
30
|
+
- lib/definition/descriptor/data_content_descriptor.rb
|
31
|
+
- lib/definition/descriptor/digital_copy_control_descriptor.rb
|
32
|
+
- lib/definition/descriptor/event_group_descriptor.rb
|
33
|
+
- lib/definition/descriptor/extended_event_descriptor.rb
|
34
|
+
- lib/definition/descriptor/short_event_descriptor.rb
|
35
|
+
- lib/definition/descriptor/unknown_descriptor.rb
|
36
|
+
- lib/definition/descriptor_list.rb
|
37
|
+
- lib/definition/eit_event.rb
|
38
|
+
- lib/definition/event_information_section.rb
|
39
|
+
- lib/definition/event_list.rb
|
40
|
+
- lib/definition/transport_packet.rb
|
41
|
+
- lib/epg.rb
|
42
|
+
- lib/parsing.rb
|
43
|
+
- lib/psi_section_reader.rb
|
44
|
+
- lib/ts.rb
|
45
|
+
- lib/tsparser.rb
|
46
|
+
- LICENSE
|
47
|
+
- README.rdoc
|
48
|
+
homepage: http://github.com/rokugatsu/tsparser
|
49
|
+
licenses:
|
50
|
+
- MIT-LICENSE
|
51
|
+
metadata: {}
|
52
|
+
post_install_message:
|
53
|
+
rdoc_options: []
|
54
|
+
require_paths:
|
55
|
+
- lib
|
56
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - '>='
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
requirements: []
|
67
|
+
rubyforge_project:
|
68
|
+
rubygems_version: 2.0.3
|
69
|
+
signing_key:
|
70
|
+
specification_version: 4
|
71
|
+
summary: Library to read MPEG2-TS.Mainly, as japanese digital broadcasting in ARIB-format.
|
72
|
+
test_files: []
|