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.
@@ -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
@@ -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
@@ -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
@@ -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: []