Saturday 24 December 2016

Raspberry Pi Kodi CEC for Yamaha A/V Receiver

CEC works out of the box on Kodi on the Pi but not if you have an A/V Receiver and a projector rather than a TV.

If can put put right in the settings in Kodi if you have a working remote but a mouse doesn't seem to do it.

Copying the relevant config file from a working system is the easiest way. For me this file gets created as:
 
/home/kodi/.kodi/userdata/peripheral_data/rpi_2708_1001.xml

2708:1001 is the device ID for the pi's CEC adapter.

The contents of my file are:

<settings>
    <setting id="activate_source" value="0" />
    <setting id="button_release_delay_ms" value="0" />
    <setting id="button_repeat_rate_ms" value="0" />
    <setting id="cec_hdmi_port" value="1" />
    <setting id="cec_standby_screensaver" value="0" />
    <setting id="cec_wake_screensaver" value="1" />
    <setting id="connected_device" value="36037" />
    <setting id="device_name" value="Kodi" />
    <setting id="device_type" value="1" />
    <setting id="double_tap_timeout_ms" value="300" />
    <setting id="enabled" value="1" />
    <setting id="pause_playback_on_deactivate" value="1" />
    <setting id="physical_address" value="0" />
    <setting id="port" value="" />
    <setting id="send_inactive_source" value="1" />
    <setting id="standby_devices" value="231" />
    <setting id="standby_devices_advanced" value="" />
    <setting id="standby_pc_on_tv_standby" value="13005" />
    <setting id="standby_tv_on_pc_standby" value="1" />
    <setting id="tv_vendor" value="0" />
    <setting id="use_tv_menu_language" value="1" />
    <setting id="wake_devices" value="231" />
    <setting id="wake_devices_advanced" value="" />
</settings>

Saturday 17 December 2016

MPEG-DASH and HLS with Gstreamer

Gstreamer does a good job with the modern streaming protocols.

The command line client gst123 can be used to listen to BBC AoD and live streams.

BBC AoD streams can be found here: BBC World Service AoD feed (replace worldservice with your channel of choice).

BBC Live streams can be found here: BBC IMDA transports

Here are some examples using gst123:

Play an MPEG-DASH stream listed in imda_transports.xml:

gst123 -q http://a.files.bbci.co.uk/media/live/manifesto/audio/simulcast/dash/nonuk/dash_low/ak/bbc_radio_three.mpd

Play an HLS stream listed in imda_transports.xml:

 gst123 -q http://a.files.bbci.co.uk/media/live/manifesto/audio/simulcast/hls/uk/sbr_vlow/llnw/bbc_radio_three.m3u8

Play an on-demand DASH stream from Radio 4 (you will need to look in the xml file for a current programme):

 gst123 -q http://open.live.bbc.co.uk/mediaselector/5/redir/version/2.0/mediaset/audio-syndication-dash/proto/http/vpid/b084d7wf

It is really easy to roll your own Gstreamer based player using python. There are some examples here.

I rolled this one by adding command line processing to basic-tutorial-1:

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
import sys
import gi
gi.require_version('Gst', '1.0')
from gi.repository import Gst
Gst.init(None)

# Build the pipeline
pipeline = Gst.parse_launch("playbin uri=%s" % sys.argv[1
# Start playing
pipeline.set_state(Gst.State.PLAYING)

# Wait until error or EOS
bus = pipeline.get_bus()
msg = bus.timed_pop_filtered(
    Gst.CLOCK_TIME_NONE, Gst.MessageType.ERROR | Gst.MessageType.EOS)

# Free resourcespipeline.set_state(Gst.State.NULL)

Then you can use the same example streams:

./gst.py http://a.files.bbci.co.uk/media/live/manifesto/audio/simulcast/dash/nonuk/dash_low/ak/bbc_radio_three.mpd

./gst.py http://a.files.bbci.co.uk/media/live/manifesto/audio/simulcast/hls/uk/sbr_vlow/llnw/bbc_radio_three.m3u8

It only takes a little more effort to make something useful. The following python3 script takes the name of a programme and the url of an AoD feed on the command line and plays the latest episode of that programme:

# Free #!/usr/bin/env python3
# -*- coding:utf-8 -*-
import sys
import gi
gi.require_version('Gst', '1.0')
from gi.repository import Gst
from xml.etree import ElementTree
from datetime import datetime
import arrow
from urllib.request import urlopen

Gst.init(None)

# Get a url

title = sys.argv[1]
feed = sys.argv[2]
now = arrow.utcnow()
wanted = now.replace(hours=-1)
with urlopen(feed) as f:
    tree = ElementTree.parse(f)
for node in tree.iter('entry'):
    for entry in node.iter('parent'):
        if entry.text == title:
            for field in node.iter():
                if field.tag == 'link' and field.attrib.get('transferformat') == 'dash':
                    thisurl = field.text
                if field.tag == 'availability':
                    start = arrow.get(field.attrib.get("start"))
                    end = arrow.get(field.attrib.get("end"))
                    if (start <= now) and (now <= end) and (start > wanted):
                        wanted = start
                        url = thisurl
# Build the pipeline
pipeline = Gst.parse_launch("playbin uri=%s" % url)

# Start playing
pipeline.set_state(Gst.State.PLAYING)

# Wait until error or EOS
bus = pipeline.get_bus()
msg = bus.timed_pop_filtered(
    Gst.CLOCK_TIME_NONE, Gst.MessageType.ERROR | Gst.MessageType.EOS)

# Free resources
pipeline.set_state(Gst.State.NULL)


So you can do this:

./bbcaod.py   "BBC News" http://www.bbc.co.uk/radio/aod/availability/worldservice.xml

Sunday 9 October 2016

Google Maps Location Sillyness

Google Maps has a funny idea of where things are.

If I view the 'my contributions' page it looks something like this


See that marker in the middle of the North Sea? And the photo on the left which says North Sea?

Now look at this image of Google Maps zoomed in to near Harwich
That's the same picture.

When I look at this on Panoramio it says the location is Harwich.
In fact it says "Photo taken in 13 Lower Marine Parade, Harwich CO12 3SS, UK
Which is clearly not true but better than "North Sea".

I can't find any way of adding names of seas, bays or channels or of changing where this is, or how come Google Maps says its in the north sea but Panoramio says its in Harwich.