LED display for Kodi

Index, feed.

[ Date | 2020-03-31 22:18 -0400 ]
[ Mod. | 2020-04-06 00:12 -0400 ]

This builds on the ESP8266-based LED clock, but can also be used on its own.

LED display showing 1h45m19s remaining

LED display showing 1h45m19s remaining

OSD (On-screen display) is one big innovation that I believe became commonplace in the 1990s: during this decade, TVs and VCRs lost their separate LCD or, more commonly, LED display, in favor of superimposing the information on the TV picture. This is mostly fine, as TVs were usually larger and more legible than the typical half-inch-tall LED display. However, this also means that one can't see how long remains on the program they are watching unless they pause it (to make the OSD appear), or accept having the time remaining being constantly displayed (which is ugly). The problem remains to this day.

The short program shown here allows having a display for time remaining on the music or video being played on Kodi.


    kodi-progress --host HOSTNAME --port PORT [--echo]

Output examples:

## When nothing is playing:

## When something short is playing:

## When something long is playing:


Full program: kodi-progress.

sub call($$$) {
    my ($ua, $url, $call) = @_;
    $call->{jsonrpc} = '2.0';
    $call->{id} = 'foo';

    return $ua->post($url,
                     'Content-Type' => 'application/json',
                     Content => to_json $call);
sub player_status_call($) {
    my $player_id = shift;
    return {
        method => 'Player.GetProperties',
        params => {
          playerid => $player_id,
          properties => [qw(time totaltime percentage)],
while (1) {
    my $response = call($ua, $url, player_status_call(1));
    $response = call($ua, $url, player_status_call(0)) if is_error($response);

    my $msg = '        ';
    if (is_error($response)) {
    } else {
        my $response_object = from_json $response->decoded_content;
        my $r = $response_object->{result};

        my $time = $r->{time};
        my $len  = $r->{totaltime};

        my $time_s =
            $time->{hours} * 3600 + $time->{minutes} * 60 + $time->{seconds};
        my $len_s =
            $len->{hours} * 3600 + $len->{minutes} * 60 + $len->{seconds};

        if ($len_s > 0) {
            my $remaining_s = $len_s - $time_s;
            my $h = int($remaining_s / 3600);
            my $m = int($remaining_s / 60) % 60;
            my $s = $remaining_s % 60;

            if ($h > 0) {
                $msg = sprintf '%d:%02d:%02d', $h, $m, $s;
                $msg = '-' . $msg if $h < 10;
            } else {
                $msg = sprintf '-%d:%02d', $m, $s;
                $msg = sprintf '%8.8s', $msg;
    printf STDERR "\r%s", $msg if $do_echo;

    my $cmd = pack 'C', 0x80;
    $sock->send($cmd . $msg) if $do_udp_send;
    sleep 0.45;

The code is very dumb and just updates the display about twice a second. It could be made more sophisticated and avoid sending updates that do not change from the previous state, or even attempt to synchronize with the rate of change of the input. This all seems a bit overkill.


LED display showing 1h45m19s remaining

LED display showing 1h45m19s remaining

This is the same as the picture at the top of this article, except rendered as vector graphics instead of a photograph.



Quick links:

Camp info 2007
Camp Faécum 2007
Japanese adjectives
Couleurs LTP
French English words
Petites arnaques
DSC-W17 patch
Scarab: dictionnaire de Scrabble
Omelette soufflée au sirop d'érable
Camembert fondu au sirop d'érable
La Mona de Tata Zineb
Cake aux bananes, au beurre de cacahuètes et aux pépites de chocolat