Last active
October 28, 2015 13:09
-
-
Save upsilon/63074ada99f986ff44d0 to your computer and use it in GitHub Desktop.
ariblibで実装したepgdump互換のXMLを出力するスクリプト
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
from ariblib import tsopen | |
from ariblib.descriptors import ServiceDescriptor | |
from ariblib.sections import ActualStreamEventInformationSection, EventInformationSection, ActualStreamServiceDescriptionSection, ServiceDescriptionSection | |
from ariblib.service import tsid2channel, Service | |
from ariblib.event import Event | |
import sys | |
from datetime import timezone, timedelta | |
import lxml.etree as etree | |
CONTENT_TYPE_EN = { | |
0x0: 'news', | |
0x1: 'sports', | |
0x2: 'information', | |
0x3: 'drama', | |
0x4: 'music', | |
0x5: 'variety', | |
0x6: 'cinema', | |
0x7: 'anime', | |
0x8: 'documentary', | |
0x9: 'stage', | |
0xA: 'hobby', | |
0xB: 'welfare', | |
0xE: 'etc', | |
0xF: 'etc', | |
} | |
services = {} | |
events = {} | |
events_long = {} | |
active_service_ids = [] | |
if sys.argv[1] in ('/BS', '/CS'): | |
channel_id = None | |
else: | |
channel_id = sys.argv[1] | |
with tsopen(sys.argv[2]) as ts: | |
for section in ts.sections(ActualStreamEventInformationSection, ActualStreamServiceDescriptionSection): | |
if isinstance(section, EventInformationSection): | |
for e in section.events: | |
event = Event(section, e) | |
event_id = event.event_id | |
if hasattr(event, 'title'): | |
events[event_id] = event | |
if hasattr(event, 'longdesc'): | |
events_long[event_id] = event | |
if event.service_id not in active_service_ids: | |
active_service_ids.append(event.service_id) | |
elif isinstance(section, ServiceDescriptionSection): | |
for s in section.services: | |
if channel_id is None: | |
channel_id = tsid2channel(section.transport_stream_id) | |
service = Service(s, channel_id) | |
service_id = service.service_id | |
if service_id not in services: | |
service.transport_stream_id = section.transport_stream_id | |
service.original_network_id = section.original_network_id | |
services[service_id] = service | |
elm_tv = etree.Element('tv', attrib = {'generator-info-name': 'tsEPG2xml', 'generator-info-url': 'http://localhost/'}) | |
for service_id in sorted(active_service_ids): | |
service = services[service_id] | |
elm_channel = etree.SubElement(elm_tv, 'channel') | |
elm_channel.attrib['id'] = '%s_%s' % (service.broadcasting_type, service.service_id) | |
elm_channel.attrib['tp'] = service.channel_id | |
elm_display_name = etree.SubElement(elm_channel, 'display-name', lang = 'ja_JP') | |
elm_display_name.text = str(service.name) | |
elm_transport = etree.SubElement(elm_channel, 'transport_stream_id') | |
elm_transport.text = str(service.transport_stream_id) | |
elm_network = etree.SubElement(elm_channel, 'original_network_id') | |
elm_network.text = str(service.original_network_id) | |
elm_service_id = etree.SubElement(elm_channel, 'service_id') | |
elm_service_id.text = str(service_id) | |
for event_id, event in events.items(): | |
start_time = event.start_time | |
end_time = event.start_time + event.duration | |
service = services[event.service_id] | |
elm_programme = etree.SubElement(elm_tv, 'programme') | |
elm_programme.attrib['start'] = start_time.strftime('%Y%m%d%H%M%S +0900') | |
elm_programme.attrib['stop'] = end_time.strftime('%Y%m%d%H%M%S +0900') | |
elm_programme.attrib['channel'] = '%s_%s' % (service.broadcasting_type, service.service_id) | |
elm_programme.attrib['event_id'] = str(event.event_id) | |
elm_title = etree.SubElement(elm_programme, 'title', lang = 'ja_JP') | |
elm_title.text = str(event.title).replace(' ', ' ') | |
elm_desc = etree.SubElement(elm_programme, 'desc', lang = 'ja_JP') | |
if event_id in events_long: | |
elm_desc.text = '%s\n\n%s' % (event.desc, events_long[event_id].longdesc) | |
else: | |
elm_desc.text = str(event.desc) | |
elm_category_ja = etree.SubElement(elm_programme, 'category', lang = 'ja_JP') | |
elm_category_en = etree.SubElement(elm_programme, 'category', lang = 'en') | |
if hasattr(event, 'genre') and event.nibble1[0] < 0x08: | |
elm_category_ja.text = str(event.genre[0]) | |
elm_category_en.text = CONTENT_TYPE_EN[event.nibble1[0]] | |
else: | |
elm_category_ja.text = 'その他' | |
elm_category_en.text = 'etc' | |
print('<?xml version="1.0" encoding="UTF-8"?>\n') | |
print('<!DOCTYPE tv SYSTEM "xmltv.dtd">\n\n') | |
print(etree.tounicode(elm_tv, pretty_print=True)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
/BS
/CS
オプションは動作未確認<desc>
に拡張形式イベント記述子の内容を追記しているので、Chinachu で出演者等の情報も閲覧・検索できるevent.nibble1[0] < 0x08
以外をetc
にしているのは epgdump のバグに合わせたため