diff options
author | Tom Ryder <tom@sanctum.geek.nz> | 2015-12-04 22:18:44 +1300 |
---|---|---|
committer | Tom Ryder <tom@sanctum.geek.nz> | 2015-12-04 22:20:58 +1300 |
commit | 429db356903983bb464028f6292a801a1483c178 (patch) | |
tree | dfe8c037eb1749a4a9e840e7ead13c150c331bc7 | |
download | mpdlrc-429db356903983bb464028f6292a801a1483c178.tar.gz mpdlrc-429db356903983bb464028f6292a801a1483c178.zip |
First commit
-rw-r--r-- | Darkthrone - To Walk The Infernal Fields.lrc | 34 | ||||
-rw-r--r-- | LICENSE | 157 | ||||
-rw-r--r-- | README.markdown | 25 | ||||
-rwxr-xr-x | mpdlrc | 149 |
4 files changed, 365 insertions, 0 deletions
diff --git a/Darkthrone - To Walk The Infernal Fields.lrc b/Darkthrone - To Walk The Infernal Fields.lrc new file mode 100644 index 0000000..f006e5f --- /dev/null +++ b/Darkthrone - To Walk The Infernal Fields.lrc @@ -0,0 +1,34 @@ +[00:35.36]From the abode of demons +[00:39.20]A wing of the pentagram +[00:43.14]Comes the juice that painted +[00:46.80]My heart and my soul +[00:50.90]Swept in black they are +[00:54.80]Swept in black I am +[00:58.63]From this soul comes eyes +[01:02.51]That will look upon your ten +[01:06.39]Beautiful heads +[01:09.40]With delight +[01:13.78]My heart is the one +[01:17.96]That will tend to your flames +[01:21.80]And make them mine +[01:25.55]We share this spirit +[01:27.44]My heart is yours +[01:52.80]I am your disciple +[01:54.16]And therefore my own +[01:56.03]Your weapon I will be +[01:57.68]With the demons that possess me +[02:00.11]We will ride the seven sins of death +[02:05.30]That takes me to Kathaaria +[02:39.60]The sign of your horns +[02:43.25]Is my dearest vision +[02:47.16]They impale all holy +[02:50.16]Holy and weak +[05:39.06]You watch me face the mirror +[05:42.47]And see the desecration +[05:46.23]With my art I am the fist +[05:50.25]In the face of God +[07:00.06]You watch me face the mirror +[07:03.47]And see the desecration +[07:07.23]With my art I am the fist +[07:11.25]In the face of God + @@ -0,0 +1,157 @@ +Artistic License 2.0 + +Copyright (c) 2000-2006, The Perl Foundation. + +Everyone is permitted to copy and distribute verbatim copies of this license +document, but changing it is not allowed. Preamble + +This license establishes the terms under which a given free software Package may +be copied, modified, distributed, and/or redistributed. The intent is that the +Copyright Holder maintains some artistic control over the development of that +Package while still keeping the Package available as open source and free +software. + +You are always permitted to make arrangements wholly outside of this license +directly with the Copyright Holder of a given Package. If the terms of this +license do not permit the full use that you propose to make of the Package, you +should contact the Copyright Holder and seek a different licensing arrangement. +Definitions + +"Copyright Holder" means the individual(s) or organization(s) named in the +copyright notice for the entire Package. + +"Contributor" means any party that has contributed code or other material to the +Package, in accordance with the Copyright Holder's procedures. + +"You" and "your" means any person who would like to copy, distribute, or modify +the Package. + +"Package" means the collection of files distributed by the Copyright Holder, and +derivatives of that collection and/or of those files. A given Package may +consist of either the Standard Version, or a Modified Version. + +"Distribute" means providing a copy of the Package or making it accessible to +anyone else, or in the case of a company or organization, to others outside of +your company or organization. + +"Distributor Fee" means any fee that you charge for Distributing this Package or +providing support for this Package to another party. It does not mean licensing +fees. + +"Standard Version" refers to the Package if it has not been modified, or has +been modified only in ways explicitly requested by the Copyright Holder. + +"Modified Version" means the Package, if it has been changed, and such changes +were not explicitly requested by the Copyright Holder. + +"Original License" means this Artistic License as Distributed with the Standard +Version of the Package, in its current version or as it may be modified by The +Perl Foundation in the future. + +"Source" form means the source code, documentation source, and configuration +files for the Package. + +"Compiled" form means the compiled bytecode, object code, binary, or any other +form resulting from mechanical transformation or translation of the Source form. +Permission for Use and Modification Without Distribution + +(1) You are permitted to use the Standard Version and create and use Modified +Versions for any purpose without restriction, provided that you do not +Distribute the Modified Version. Permissions for Redistribution of the Standard +Version + +(2) You may Distribute verbatim copies of the Source form of the Standard +Version of this Package in any medium without restriction, either gratis or for +a Distributor Fee, provided that you duplicate all of the original copyright +notices and associated disclaimers. At your discretion, such verbatim copies may +or may not include a Compiled form of the Package. + +(3) You may apply any bug fixes, portability changes, and other modifications +made available from the Copyright Holder. The resulting Package will still be +considered the Standard Version, and as such will be subject to the Original +License. Distribution of Modified Versions of the Package as Source + +(4) You may Distribute your Modified Version as Source (either gratis or for a +Distributor Fee, and with or without a Compiled form of the Modified Version) +provided that you clearly document how it differs from the Standard Version, +including, but not limited to, documenting any non-standard features, +executables, or modules, and provided that you do at least ONE of the following: + +(a) make the Modified Version available to the Copyright Holder of the Standard +Version, under the Original License, so that the Copyright Holder may include +your modifications in the Standard Version. (b) ensure that installation of your +Modified Version does not prevent the user installing or running the Standard +Version. In addition, the Modified Version must bear a name that is different +from the name of the Standard Version. (c) allow anyone who receives a copy of +the Modified Version to make the Source form of the Modified Version available +to others under (i) the Original License or (ii) a license that permits the +licensee to freely copy, modify and redistribute the Modified Version using the +same licensing terms that apply to the copy that the licensee received, and +requires that the Source form of the Modified Version, and of any works derived +from it, be made freely available in that license fees are prohibited but +Distributor Fees are allowed. Distribution of Compiled Forms of the Standard +Version or Modified Versions without the Source + +(5) You may Distribute Compiled forms of the Standard Version without the +Source, provided that you include complete instructions on how to get the Source +of the Standard Version. Such instructions must be valid at the time of your +distribution. If these instructions, at any time while you are carrying out such +distribution, become invalid, you must provide new instructions on demand or +cease further distribution. If you provide valid instructions or cease +distribution within thirty days after you become aware that the instructions are +invalid, then you do not forfeit any of your rights under this license. + +(6) You may Distribute a Modified Version in Compiled form without the Source, +provided that you comply with Section 4 with respect to the Source of the +Modified Version. Aggregating or Linking the Package + +(7) You may aggregate the Package (either the Standard Version or Modified +Version) with other packages and Distribute the resulting aggregation provided +that you do not charge a licensing fee for the Package. Distributor Fees are +permitted, and licensing fees for other components in the aggregation are +permitted. The terms of this license apply to the use and Distribution of the +Standard or Modified Versions as included in the aggregation. + +(8) You are permitted to link Modified and Standard Versions with other works, +to embed the Package in a larger work of your own, or to build stand-alone +binary or bytecode versions of applications that include the Package, and +Distribute the result without restriction, provided the result does not expose a +direct interface to the Package. Items That are Not Considered Part of a +Modified Version + +(9) Works (including, but not limited to, modules and scripts) that merely +extend or make use of the Package, do not, by themselves, cause the Package to +be a Modified Version. In addition, such works are not considered parts of the +Package itself, and are not subject to the terms of this license. General +Provisions + +(10) Any use, modification, and distribution of the Standard or Modified +Versions is governed by this Artistic License. By using, modifying or +distributing the Package, you accept this license. Do not use, modify, or +distribute the Package, if you do not accept this license. + +(11) If your Modified Version has been derived from a Modified Version made by +someone other than you, you are nevertheless required to ensure that your +Modified Version complies with the requirements of this license. + +(12) This license does not grant you the right to use any trademark, service +mark, tradename, or logo of the Copyright Holder. + +(13) This license includes the non-exclusive, worldwide, free-of-charge patent +license to make, have made, use, offer to sell, sell, import and otherwise +transfer the Package with respect to any patent claims licensable by the +Copyright Holder that are necessarily infringed by the Package. If you institute +patent litigation (including a cross-claim or counterclaim) against any party +alleging that the Package constitutes direct or contributory patent +infringement, then this Artistic License to you shall terminate on the date that +such litigation is filed. + +(14) Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND +CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR +NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL LAW. +UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING IN ANY WAY +OUT OF THE USE OF THE PACKAGE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +DAMAGE. + diff --git a/README.markdown b/README.markdown new file mode 100644 index 0000000..2780efb --- /dev/null +++ b/README.markdown @@ -0,0 +1,25 @@ +mpdlrc +====== + +Print timed lyrics from an LRC file for MPD's currently playing song +line-by-line to `stdout`: <https://en.wikipedia.org/wiki/LRC_%28file_format%29> + +Expects to find lyrics named `Artist - Title.lrc` in `~/.lyrics`. + +This code is not great. It will be improved. It needs to be more configurable +from environment variables or options, for one thing. + +This could maybe be used with `dzen` or a similar desktop notification tool to +display lyrics in a corner as you work on other things. + +An LRC file I made for Darkthrone's "To Walk The Infernal Fields" from their +1993 album "Under a Funeral Moon" is included for testing. + +License +------- + +Copyright (c) [Tom Ryder][1]. Distributed under [Artistic License 2.0][2]. + +[1]: https://sanctum.geek.nz/ +[2]: http://opensource.org/licenses/artistic-license-2.0 + @@ -0,0 +1,149 @@ +#!/usr/bin/env perl + +# +# mpdlrc -- Print timed lyrics from an LRC file for MPD's currently playing +# song line-by-line to stdout. See README.markdown. +# +# Author: Tom Ryder <tom@sanctum.geek.nz> +# Copyright: 2015 +# +package Sanctum::Mpdlrc; + +# Force me to write this properly +use strict; +use warnings; +use utf8; +use autodie qw(:all); + +# Require a few modules +use Carp; +use Const::Fast; +use Net::MPD; +use Time::HiRes qw(sleep); + +# Require at least Perl 5.12 +use 5.012; + +# Specify version number +our $VERSION = 0.1; + +# Specify some constants to appease Perl::Critic +const my $SECONDS_PER_MINUTE => 60; +const my $HUNDREDTHS_PER_SECOND => 100; + +# Connect to MPD, or give up and cry +my $mpd = Net::MPD->connect() + or croak('Failed to connect to MPD'); + +# We declare the PID outside of the main loop so we can kill it on subsequent +# iterations of the loop, should we need to restart the process. +my $pid; + +# Use UTF-8 for output, because forëigñ charåcters āre ìmpørtánt +binmode *STDOUT, ':encoding(utf8)'; + +MPD: while (1) { + + # Something important happened; kill any running lyric processes + if ($pid) { + kill 'INT', $pid; + } + + # Get the current status + my $status = $mpd->update_status(); + + # If there's a song playing, we'll try and spit some lyrics + if ( $status->{state} eq 'play' ) { + + # Get details about the current song + my $song = $mpd->current_song(); + + # Fork a new process + $pid = fork; + + # This block should only be run by the fork + if ( !$pid ) { + + # Build the expected filename for the lyric file from the song's + # author and title + my $lfn = sprintf '%s/.lyrics/%s - %s.lrc', $ENV{HOME}, + @{$song}{qw(Artist Title)}; + + # If no such file exists, we have failed + if ( !-e $lfn ) { + exit 1; + } + + # Read a lyrics queue object from the file, providing it with the + # elapsed time (i.e. telling it how far into the song we already + # are) + my $lyrics = read_lyrics_queue( $lfn, $status->{elapsed} ); + + # Step through the lyrics queue object, sleeping the required + # amount of time before printing each line of text to stdout + foreach my $lyric ( @{$lyrics} ) { + sleep $lyric->{delay}; + printf {*STDOUT} "%s\n", $lyric->{text}; + } + } + } + + # Wait for something else to happen to the player, whether or not there's a + # forked process going + $mpd->idle('player'); +} + +# Subroutine to read lyrics from the given filename and return a queue object +# specifying a list of lyrics to display and how long to wait before displaying +# each line +sub read_lyrics_queue { + my ( $lfn, $elapsed ) = @_; + $elapsed //= 0; + + # Read the file into a list of lines + open my $lfh, q{<:encoding(utf8)}, $lfn; + my @lines = readline $lfh; + close $lfh; + + # Start a list of lyric hashrefs + my @lyrics; + + # Read each line + LINE: foreach my $line (@lines) { + + # Get rid of trailing newlines + chomp $line; + + # If the line is in LRC format, we'll queue it up + if ( $line =~ m{\[(\d+):(\d+)[.](\d+)\](.+)}msx ) { + + # Read minutes, seconds, hundredth-seconds, and text from the + # matches in the line + my ( $min, $sec, $hsec, $text ) = ( $1, $2, $3, $4 ); + + # Flatten out the times into a number of seconds, fractional + # (that's why we need sleep() from Time::HiRes) + my $tsec = + ( $min * $SECONDS_PER_MINUTE ) + + $sec + + ( $hsec / $HUNDREDTHS_PER_SECOND ); + + # If the lyric is yet to be displayed, i.e. we haven't already + # passed the appropriate point in the song, queue it up and + # increment the elapsed time for queuing up the next lyric, if any + if ( $tsec > $elapsed ) { + my $lyric = { + delay => $tsec - $elapsed, + text => $text, + }; + push @lyrics, $lyric; + $elapsed += $lyric->{delay}; + } + + } + } + + # Return a reference to the built lyric object + return \@lyrics; +} + |