Skip to content

Instantly share code, notes, and snippets.

@upsilon
Last active October 28, 2015 13:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save upsilon/63074ada99f986ff44d0 to your computer and use it in GitHub Desktop.
Save upsilon/63074ada99f986ff44d0 to your computer and use it in GitHub Desktop.
ariblibで実装したepgdump互換のXMLを出力するスクリプト
#!/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))
@upsilon
Copy link
Author

upsilon commented Oct 28, 2015

  • /BS /CS オプションは動作未確認
  • <desc> に拡張形式イベント記述子の内容を追記しているので、Chinachu で出演者等の情報も閲覧・検索できる
  • 元の epgdump と違って英数字が全て半角で出力されるため、既存の録画ルールを修正する必要がある
  • 107行目付近で event.nibble1[0] < 0x08 以外を etc にしているのは epgdump のバグに合わせたため

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment