blog.humaneguitarist.org

discoveries in digital audio, music notation, and information encoding

on adding a JavaScript API to our Flash player at work

leave a comment

Sometimes being home sick means finding things to work on that I wouldn't have done had I been in the office, but need to be done eventually.

So, today I worked on augmenting a JavaScript API for our Flash player at work. Before I go any further, here's a screenshot below. Note that the JavaScript console for Googles' Chrome browser is visible at the bottom.

NC Live Media Player

As you can see, the "movie" is not just the "movie", so to speak. That's to say, there's a very cool bookmarking feature that, if clicked, returns a URL that if visited will start the given video at the point in time at which the user clicked the bookmark. The "movie" also includes some whitespace on the left hand side where links to "part 2"s of certain videos appear if they exist. That's great, but it totally makes our Flash player inappropriate for providing embed codes, etc. since the "movie" is more than the actual video screen and the controls (play, pause, captions, etc.). And, yes, we have to use our own player given that we have to deal with all kinds of authentication and rights issues, which this player support via calls to PHP scripts.

Anyway, a few months ago I'd created a basic JavaScript API so that I could make a demo using our player for SAVS, which is completely reliant on two things: being able to receive the current time of the player and also being able to send a new current time to the player.

Today, I expanded the API a little bit though in the image above you can see a call to the function that moves, in the case above, the player to the 10 second mark. I added support for changing the volume, pausing the video, playing the video if it's paused, turning captions on/off, and getting the total duration of the media file, etc. Basically, I'm trying to add support for anything we'd need to replace the bookmark button and other features with HTML buttons, etc.

There's still lots of work to do, but it's working well provided I embed the SWF file with the <object> tag:

<object
  id="thisMovie"
  data="video2_js.swf"
  style="height: 500px; width: 500px;"
  type="application/x-shockwave-flash">
  <param name="movie" value="video2_js.swf" />
</object>

Then I can use these JavaScript functions on the page that embeds the player …

<script type="text/javascript">
//see: http://kirill-poletaev.blogspot.com/2011/02/exchange-data-between-actionscript-3.html
function getFlashMovie(movieName) {
  var isIE = navigator.appName.indexOf("Microsoft") != -1;
  return (isIE) ? window[movieName] : document[movieName];
}

// ... more functions were here, but there's too much for a blog post. :-]

function ncl_getCurrentTime() {
  var callResult = getFlashMovie("thisMovie").getCurrentTime("");
  return callResult;
}

function ncl_getTotalTime() {
  var callResult = getFlashMovie("thisMovie").getTotalTime("");
  return callResult;
}
</script>

… provided I make sure the ActionScript in the Flash player is prepared for those callbacks …

//see: http://kirill-poletaev.blogspot.com/2011/02/exchange-data-between-actionscript-3.html

//send current time value to JavaScript function
function sendCurrentTimeToJS(name:Number):Number
{
    var now:int = cfp.playheadTime;
    return now;
}
ExternalInterface.addCallback("getCurrentTime", sendCurrentTimeToJS);

//send total time value to JavaScript function
function sendTotalTimeToJS(name:Number):Number
{
    var total:int = cfp.totalTime;
    return total;
}
ExternalInterface.addCallback("getTotalTime", sendTotalTimeToJS);
--------------

Related Content:

Written by nitin

February 23rd, 2012 at 6:14 pm

Posted in scripts

Tagged with , , ,

do you two know each other? Bash meet Python

leave a comment

I'm working on a cool project at work that's about harvesting metadata, indexing it with Solr, and providing a simple UI so that people wanting to search for digital items from North Carolina libraries can have some fun searching from a single interface. It's fun working with other people re: making decisions and all, but also with coding. I'm totally the "backend" guy re: harvesting metadata and indexing and the UI is being handled, very awesomely, by one of the programmers who works at one of the partner institutions. Once the site's up and running on a non-development server (hopefully in just a few weeks), I'll offer up more information and a link or two.

Anyway, once a user makes a selection through the UI and clicks on a link, they go straight to the corresponding page on the originating website. Right now, everything is using an OAI feed for the pilot project, but the Python script that does the harvesting can support lots of other things, like WordPress sites, for example, by harvesting RSS feeds or whatever.

It's nothing new, but what we have works and has a very small footprint in terms of scripts and setup files. The only real requirements are that the data be openly available via HTTP and that there's a programmatic way to construct a new URL to get the next "batch" of metadata.

For instance:

http://blog.humaneguitarist.org/?feed=rss&paged=1

http://blog.humaneguitarist.org/?feed=rss&paged=2

etc.

… oh and that the data be parse-able by XSLT 1.0, but as I mentioned before I'll eventually add support, in an extensible manner, for what I hope is just about any scripting language.

Anyway, I wanted to set up a cron job to run the harvester, so I wrote a Bash script that runs the harvester and the cron job in turn runs the Bash script.

All the partners involved for the pilot agreed that we'd harvest and index every two weeks. Currently, I'm running it nightly, but same difference. The real thing I want to say is that, after harvest, I delete the entire index before re-indexing. This keeps the thing up-to-date and prevents old items from lingering in the index if, in fact, they've been taken down from the originating collection. And, let's face it, that's the reality of it. Things change.

Of course, this entails a huge risk. If something goes wrong with the harvesting script (which is still in it's early stages of development) or with one or more of the feeds, then deleting the index is potentially disastrous. So I discussed this with our main IT/programming guy in the office. And he said, "You gotta make your Python script talk to your Bash script."

What he meant was that while the Python script will push through most issues, foreseen and not, I needed the Python script to report if something went wrong with a feed or whatnot along the way. So, what I did was simply set it to print a "0" if all went well and a "1" if anything I identified as a point of concern occurred: Python script failed, one of the feeds returned a non-200, etc. The Bash script, in turn, reads this output and will only delete the index if a "0" was returned by the Python script, called "pOAIndexter.py".

So, here's the Bash. I think the logic is laid out well enough with the echo statements, so I'll just cough it up, as is, below:

#!/bin/bash

#####
echo "HARVESTING metadata (this may take a long time)."
cd /srv/heritageIndexing/pOAIndexter
output=$(./pOAIndexter.py)
echo ""

echo "Return code:" $output
echo ""

#####
cd /srv/heritageIndexing/apache-solr-3.4.0/example/exampledocs
if [ $output != "0" ]; then
 echo "NOT deleting existing index."
else
 echo "DELETING existing index."
 java -Ddata=args -jar post.jar "<delete><query>*:*</query></delete>"
fi
echo ""

#####
echo "INDEXING harvested metadata."
java -jar post.jar /srv/heritageIndexing/pOAIndexter/output/*.xml
echo ""

#####
echo "DELETING temporary harvested metadata files."
cd /srv/heritageIndexing/pOAIndexter
rm output/*.xml
echo ""

#####
echo "Farewell."
--------------

Related Content:

Written by nitin

February 19th, 2012 at 7:56 am

just goofin’ with a little Python CSV function and a limerickesque

leave a comment

This is probably a total waste of anyone's time but  …

The other night, after I'd worked on the Aguado Rondo (Op. 2, #2), I started goofing around with a little Python function that would turn a delimited text file into a Python dictionary, allowing me to target a specific cell in a delimited file, i.e. a "spreadsheet", without using the CSV module.

It works (well, at least I hope it does) this way:

films = csv2dict("films.txt", ";") #pass filename and delimiter
print films["title"] #print "title" column sans the header
print films["title"][-1] #prints last cell in the "title" column

It seems helpful to be able to do this. I've tested it with a UTF-8 file to write to file with some accent markings on people's names, etc. but I'm pretty sure it'll break on stuff I haven't thought of.

Anyway, maybe it'll come in handy to me for something.

Here's the function:

def csv2dict(fileName, delimiter):
  f = open(fileName, "r") #open file
  lines = f.read() #read file
  f.close() #close file

  rows = lines.split("\n") #put lines in list
  headers = rows[0].split(delimiter) #put header titles in list
  rows.pop(0) #remove header from "rows" list

  i = 0
  worksheet = {}
  for header in headers: #for each header, i.e. each column
    columnCells = []
    for row in rows: #for each non-header row in delimited file
      if row != "":
        rowCells = row.split(delimiter) #get cells in row
        columnCells.append(rowCells[i]) #put column's cells in list
    worksheet[header] = columnCells #set header as KEY and set "columnCells" list as VALUE
    i = i + 1

  return worksheet

And for any guitarists out there, here's a little silly rhyme I wrote when living in my home eternal, Charleston, SC. I know the Sor as "warrior against the French" thing isn't accurate, but it helps the punchline.

:P

The title is, of course, that as Sor's famous duet.

"Le Deux Ami"

Fernando Sor,
who served in the war,
fought Bonaparte in the army.

But Dionisio Aguado,
who lacked such bravado,
preferred to run home to his mommy.
--------------

Related Content:

Written by nitin

February 16th, 2012 at 8:44 pm

motivation be damned, just wait for someone else to do it and sleep more

leave a comment

So, a few weeks ago I said in these posts that I thought it was an oversight that the HTML5 audio and video elements didn't let one pass start and stop time parameters, allowing one to use specific portions of an audio or video file.

Well, I just saw on this page that Mozilla has implemented this functionality per the Media Fragments URI Specification. And it seems that Webkit is there, too, per this post from a few weeks ago. Actually, that post was published the same week as when I started fiddling with a pure JavaScript and "data-" attribute solution when I went home sick from work. Now I wish I had just napped more that day and just waited to learn more about these implementations to take place.

Know what's funny? I never saw these docs when I wrote the aforementioned posts. Perhaps that's because the pages I linked to above about Mozilla/Webkit were last updated within just a few days of mine. But anyway, I found them today because I saw someone came to my page searching for "<audio> starttime" and I wanted to see what else came up for that query so I "Googled" it. Sometimes it's educational and not just an exercise in vanity to know why people come to your site, huh?

ZZZ …

;)

--------------

Related Content:

Written by nitin

February 7th, 2012 at 9:11 am

Posted in digital audio

Tagged with , ,

audio transcription and the undead

leave a comment

Let's forget the fact I've blogged more this month than I intend to in a whole year …

What I really want to mention is that I'm reading Dracula by Bram Stoker and noticed these very interesting bits (or should I say 'bites'?) in Chapter 17.

In this chapter the character of Mina Harker is becoming acquainted with a friend of her now dead friend, Lucy. This friend, Dr. Seward, uses a phonograph to record his patient notes, much as my dad used to use a micro-cassette back in the late 1970's and 1980's. Mina, on the other hand, uses her cutting edge writing tool, the typewriter, to make her diary entries easily readable.

The funny thing is that Seward confesses to Mina that he doesn't have a way to get to specific points within each recording, i.e. he doesn't have a way to denote and retrieve audio at a specific time with advanced knowledge of what passages exist at those points. Um, sound familiar?

:P

MINA HARKER'S JOURNAL

29 September.

Again he paused, and I could see that he was trying to invent an excuse. At length, he stammered out, "You see, I do not know how to pick out any particular part of the diary."

I could not but smile, at which he grimaced. "I gave myself away that time!" he said. "But do you know that, although I have kept the diary for months past, it never once struck me how I was going to find any particular part of it in case I wanted to look it up?"

Mina goes on to transcribe his recordings so that the text can be compared with other diary entries by principal characters as they try to formulate the totality of Dracula's agenda.

DR. SEWARD'S DIARY

30 September.

Harker has gone back, and is again collecting material. He says that by dinner time they will be able to show a whole connected narrative. He thinks that in the meantime I should see Renfield, as hitherto he has been a sort of index to the coming and going of the Count. I hardly see this yet, but when I get at the dates I suppose I shall. What a good thing that Mrs. Harker put my cylinders into type! We never could have found the dates otherwise.

Update (or "later" as in the novel): It might be a nice homage to sync the transcript to the audio of Orson Welles' radio play based on the book.

    Written by nitin

    January 31st, 2012 at 11:22 pm

    VPS’ ain’t cheap: MXMLiszt demo no longer online

    leave a comment

    Just FYI:

    The live demo for MXMLiszt is no more.

    I decided to save money and stop paying monthly rates for a VPS on KickAssVPS.com that was originally purchased because I needed to have a live demo for my research while in graduate school. I've been out of school for a while and now it's time to move on.

    --------------

    Related Content:

    Written by nitin

    January 31st, 2012 at 6:55 pm

    Posted in news

    Tagged with ,

    geo this, geo that: easy acquisition of KML files with BatchGeo

    leave a comment

    Geolocation/geocoding is so "hip" these days. Everyone's so obsessed where where they and other things are. There's almost a comparison with 3-D filmmaking …

    Funny. Not too many folks seem all that concerned with when things are.

    Anyway …

    At work, we have a database with all the libraries we serve and their addresses. And the other week we needed to quickly make a map with all their locations.

    If necessity is the mother of invention, laziness is it's favorite uncle.

    Enter BatchGeo. We were able to take those values from our database and get a map generated in minutes. But it gets better.

    One of the nice things about this process is that in addition to a map, you also get a KML file download option. Taking this little XML file, it's a simple process (via XSL or other) to make a delimited file containing the inputted names of institutions and their latitude and longitude (altitude is also available).

    From there, it's not brain surgery to get those coordinates into a database and using an SQL JOIN to be able to push out an institution's name and now its coordinates, too, whenever.

    Just in case someone wants/needs to do something similar with an address book or a list of businesses, etc.

    --------------

    Related Content:

    Written by nitin

    January 28th, 2012 at 9:52 am

    Posted in technophilia,XML

    Tagged with , , , ,

    holy silence: the art of movie theaters

    leave a comment

    Tonight's a bust. I over-napped after work and now, as I listen to some Josquin des Prez, I think the most I can do tonight is write a little blog post and then go out for a beer.

    I saw "The Artist" this weekend. I don't give a rip about critics and awards, etc. but, having said that, this one reaches the heights of sublimity.

    movie poster for The Artist

    This is the first time I've seen a silent, well mostly silent, film on the big screen. Big images and big music. It was really beautiful and sorrowful to think how this has been sublimated to talkies and now the "everything must be in 3-D" way. It's a good reminder in general, but also in the library context, that new and newer technology isn't necessarily better. It's just different. With every gain, something is lost.

    Watching the film also reminded me of a newsletter entry and interview I worked on during my time at SCIWAY.net. I interviewed John Coles and Mark Tiedje of SCMovieTheatres.com about their research into South Carolina movies and movie theaters of the past. You can read the newsletter entry here and the interview here.

    When my co-worker Cedric and I interviewed John and Mark, we did so at the Majestic Grill in Charleston, SC. Sadly, like many old movie theaters the restaurant and all its crazy film memorabilia are no longer being shown, as it were. The interview lasted well over four hours; there was just too much great stuff we learned. I still remember I'd talked to John and Mark about watching some old Saturday serials together. In particular, we talked a little about this Batman serial from the 1940's I'd recently seen and how it was total war propaganda replete with racial slurs toward the "enemy".

    Well, I'm feeling like George Valentin from "The Artist" – old and washed up in my nostalgia for the past. Like him, I think I'll turn to the bottle, but for me it's going to be of the beer variety.

      Written by nitin

      January 24th, 2012 at 9:31 pm

      trying to easily format Solr results as HTML with Python

      leave a comment

      Just a quick Saturday morning post …

      One of the nice things about Solr is the ability to pass parameters that will return the results in various formats, including a Python dictionary.

      I wanted to see if I could whip up a little function that would let me pass to it both the name of a Solr element (like "title") and then the HTML element I want it mapped to.

      It doesn't seem that bad, and is a good reminder that building UIs is in large part about parsing data into HTML, upon which things like CSS and JavaScript can enter and act re: display and interface.

      Anyway, so here's an example of some code that gets five results from a Solr instance and then uses the function I wrote to output some HTML elements:

      import urllib2 as urllib
      
      ### first, get 5 Solr results formatted as a Python dictionary
      query_url = 'http://data.twigkit.com/solr-gutenberg/select/?q=poe&version=2.2&start=0&rows=5&wt=python&explainOther'
      solr = urllib.urlopen(query_url).read() #read the results
      print type(solr) #returns that it's a string :-[
      solr = eval(solr) #turns the string into a dictionary. yay.
      print type(solr) #returns that it's now a dictionary!
      
      ### second, write a function that converts stuff to HTML
      def pysolr2html(tagIn, tagOut):
          tagVal = solr['response']['docs'][i][tagIn]
          htmlVars = (tagOut, tagIn, tagVal, tagOut)
          return '<%s class="solr_%s">%s</%s>' %htmlVars
      
      ### third, iterate over the response
      i = 0
      for doc in solr['response']['docs']:
          print pysolr2html('id','span')
          print pysolr2html('title','p')
          i = i + 1
      

      And here's the output from IDLE:

      >>>
      <type 'str'>
      <type 'dict'>
      <span class="solr_id">etext8893</span>
      <p class="solr_title">Selections from Poe</p>
      <span class="solr_id">etext9511</span>
      <p class="solr_title">Several Works by Edgar Allan Poe</p>
      <span class="solr_id">etext9512</span>
      <p class="solr_title">The Works of Edgar Allan Poe, Volume 1</p>
      <span class="solr_id">etext9516</span>
      <p class="solr_title">The Works of Edgar Allan Poe, Volume 5</p>
      <span class="solr_id">etext9513</span>
      <p class="solr_title">The Works of Edgar Allan Poe, Volume 2</p>

      I'll probably do this with PHP in the end and see how easy it might be to make a small Solr wrapper, kind of like Tempo which is super light-weight. But for now, I need to remind myself it's the weekend.

      :P

      --------------

      Related Content:

      Written by nitin

      January 21st, 2012 at 12:03 pm

      Hammer prepares to nail restoration efforts

      leave a comment

      From the folks at the Brutal as Hell website:

      Here’s some killer news for fans of Hammer Horror. Yesterday Hammer announced that they would be partnering with several film outlets to bring over 30 of their classic horror flicks to Blu-ray in the coming months and years … What makes this a notable project is that Hammer is investing heavily in the restoration of these films, as opposed to taking the lazy man’s road and creating basic upconverted dumps.

      source: Hammer Films to Launch Monumental Restoration Project | Brutal As Hell. Retrieved January 20, 2012, from http://www.brutalashell.com/2012/01/hammer-films-to-launch-monumental-restoration-project/

      You can read more at Hammer's official WordPress blog here.

      I don't have a Blu-ray player, but this should eventually be good news for streaming, too. Gawd, I wish I was in the film restoration business.

      --------------

      Related Content:

      Written by nitin

      January 20th, 2012 at 11:33 pm

      Posted in film,news

      Tagged with ,

      Switch to our mobile site