This script will put make the top post of your LiveJournal reflect the music you're listening to in your Winamp, in near-realtime.
The requirements and settings are all in the code below. Note you will need a slightly modified Winamp::Control which adds user-configurable passwords.

I should note that at the moment there is a slight delay between deleteing the old post and posting the new one, so the box for Current Music will sometimes be missing. If you increase the update interval, this will be less noticeable.

Assuming I'm at my cowputer, you can see this in action at my livejournal. It's not very interesting... yet. :-)
##### Winamp -> LiveJournal ##### # winamp2lj.pl # # Author: Joshua Thomas (jthomas @ poweronemedia dot com) # Version: 0.01 # Platform: Win32 # Copyright: GNU Public License (http://www.gnu.org) # # This script will make the top entry in your LiveJournal reflect # the music playing in your Winamp. It is smart enough to detect # when you're skipping around or not listening to anything. # # Requires: Modified Winamp::Control (added password option) # (http://cowbert.2y.net/~ibanix/winamp-control-0.02-new.tar) # # LJ::Simple, and Winamp httpQ plugin also required. # httpQ was last seen at: http://www.kostaa.com/winamp # Install the modules. Activate the plugin, chose a password and port. # Edit variables (below) to reflect settings, and let 'er rip. # # Great canidate to run as a NT/2K/XP service via FireDaemon. # ################################### use strict; use warnings; use LJ::Simple; use Winamp::Control; # These three should reflect settings in the httpQ module my $host = "localhost"; my $port = 4800; my $pass = "somepassword"; # How often to update my $interval = 10; # How far to look back to delete entry # Shouldn't have to mess with this unless you update really often my $lookback = 3; my $before = undef; my @opts = ( $lookback, $before ); # undef = never timeout # anything else = die if can't talk to server after X seconds # my $timeout = 60; # $LJ::Simple::Timeout = $timeout; undef $LJ::Simple::timeout; my %Entries=(); my %new_entry=(); # LJ connection # Change to reflect your LJ username/password my $lj = new LJ::Simple ( { user => "MyUserNameHere", pass => "MyPasswordHere", pics => 0, moods => 0, } ); # Winamp control my $winamp = Winamp::Control->new( host => $host, port => $port, pass +=> $pass ) || die "Could not connect: $!\n"; my $skipping_entry = "<i>Skipping Around....</i>\n"; my $not_playing_entry = "<i>Music is Off!</i>\n"; my $subject = "<b>Current Music</b>"; LOOP: while (sleep $interval) { # Get old post if any (defined $lj->GetEntries(\%Entries,undef,"lastn",@opts)) || die "$ +0: Failed to get entries - $LJ::Simple::error\n"; # If we find a match (after startup, we should!), delete foreach my $Entry (values %Entries) { my $subj=$lj->GetSubject($Entry); if ($subj eq $subject) { my ($item_id,$anum,$html_id)=$lj->GetItemId($Entry); $lj->DeleteEntry($item_id) || die "$0: Failed to delete jo +urnal entry - $LJ::Simple::error\n"; print "Deleted old entry #: $item_id\n"; } } # Now we can slurp relevant Winamp info my $id3title = $winamp->getid3tag_songname(); my $id3artist = $winamp->getid3tag_artist(); my $id3album = $winamp->getid3tag_album(); my $id3year = $winamp->getid3tag_year(); my $id3genre = $winamp->getid3tag_genre(); my $id3comment = $winamp->getid3tag_comment(); my $current_title = $winamp->getcurrenttitle(); my $is_playing = $winamp->isplaying(); my $pos = $winamp->getoutputtime( a => 0); $pos /= 1000; # Build output for LJ my $text_title_only = "Song: \t<i>$current_title</i>\n"; $text_title_only .= "<i>Extended info not available</i>"; my $text_id3_tags = "Title: \t<i>$id3title</i>\n"; $text_id3_tags .= "Artist: \t<i>$id3artist</i>\n"; $text_id3_tags .= "Album: \t<i>$id3album</i>\n"; $text_id3_tags .= "Year: \t<i>$id3year</i>\n"; $text_id3_tags .= "Genre: \t<i>$id3genre</i>\n"; $text_id3_tags .= "Comment: \t<i>$id3comment</i>"; # LJ entry header $lj->NewEntry(\%new_entry) || die "$0: Failed to prepare new post +- $LJ::Simple::error\n"; # Pick our entry text depending on what's going on # Order of these is important! $lj->SetEntry(\%new_entry, $text_title_only) if not ($id3title); $lj->SetEntry(\%new_entry, $text_id3_tags) if ($id3title); $lj->SetEntry(\%new_entry, $skipping_entry) if ($pos < 10); $lj->SetEntry(\%new_entry, $not_playing_entry) if ($is_playing != +1); # Set subject $lj->SetSubject(\%new_entry, $subject) || die "$0: Bad set subject + line\n"; # Uncomment this to make the post private. Really just for debuggi +ng. # $lj->SetProtectPrivate(\%new_entry) || die "$0: Failed to protec +t via private - $LJ::Simple::error\n"; # Post it, sucka my ($item_id, $anum, $html_id) = $lj->PostEntry(\%new_entry); defined $item_id || die "$0: Failed to submit new journal entry - +$LJ::Simple::error\n"; print "I posted new entry #: $item_id\n"; }
Cheers,
ibanix

update (broquaint): added <readmore> tags

Replies are listed 'Best First'.
Re: Winamp -> LiveJournal
by Asim (Hermit) on Dec 15, 2002 at 16:36 UTC

    I would make one recommendation -- offer a version that posts, say, the last X songs every hour. This is so users don't pound the crap out of the LJ servers.

    ----Asim, known to some as Woodrow.

Re: Winamp -> LiveJournal
by ibanix (Hermit) on Dec 16, 2002 at 02:11 UTC
    I've been trying to figure out how to make the updates as seemless as possible. Part of the problem is that posting takes a good amount of time to resolve. Calling a delete and then an immediate post can still have a delay of upwards of 5 seconds!

    Any thoughts on how to make this more atomic?

    Cheers,
    ibanix

    $ echo '$0 & $0 &' > foo; chmod a+x foo; foo;

      ++ibanix, nice script!

      Having recently had the opportunity to work with LJ::Simple, and being a fellow LJer myself, I enjoyed the timeliness of this post. Since LJ has the option for "Current Music" with every post, I thought of another way you could implement it, which might also solve the slow update problem.

      Instead of posting a new entry with just your current musical selection, what if you modified the "Current Music" value of the most recent entry, keeping it current with whatever you are listening to? You could use the GetEntries() method with a $type of "one". Since the script is running continuously, you could store the $item_id and original "Current Music" value (which you entered manually when you first made the post), and if it detects a new post (the $item_id stored no longer matches the most recent post), it can reset the old post to the original music setting, store the new $item_id and current music, and off you go.

      ... After writing the first half of this post, I decided to go play with LJ::Simple for a bit and see if I could do what I was proposing. It turns out that the code I had in mind...

      my $entries = {}; $lj->GetEntries($entries, undef, 'one', -1); for my $item_id (keys %{$entries}) { $lj->Setprop_current_music($entries->{$item_id}, $music); $lj->PostEntry($entries->{$item_id}); }

      ...doesn't work. Apparently the hash returned by GetEntries isn't compatible with PostEntry. It looks like instead you'd have to copy all the properties from the GetEntries hash into a new entry and post that after deleting the old one. This, of course, no longer solves the problem of a delay between deleting and reposting. It even introduces a more significant issue, since the post you're deleting is an actual entry, instead of just the current music. I'm sure it can be done, and I'd like to play with it some more, but it's getting late and I've got to work in the morning. Thanks again for the great idea, this happened to be very on-topic for me at the moment. :)

        Yes, I found myself wishing that LJ::Simple had a ModifyEntry method, as it would have made all of this so much easier. I like your idea too, but I wanted to display the full ID3 tag info :-)

        This also still has the "delete & re-add" problem, I think. If you posted a new entry via the PostEntry method, you'd keep adding new entries.

        Maybe I'll have to grok the LJ::Simple source now... :-P

        Cheers,
        ibanix

        $ echo '$0 & $0 &' > foo; chmod a+x foo; foo;
Re: Winamp -> LiveJournal
by batkins (Chaplain) on Dec 16, 2002 at 02:48 UTC