RubyLearning Blog

All about Ruby and Ruby on Rails

RubyLearning Blog header image 1

A Teeny-weeny mp3 player using Ruby and Shoes

May 31st, 2008 · 7 Comments · Ruby

By Satoshi Asakawa

Satoshi AsakawaSatoshi Asakawa is a Japanese Ruby enthusiast, a former student and now an Asst. Teacher of the FORPC101 course.

Shoes is a cross-platform, tiny graphics and windowing toolkit for the Ruby programming language written by Why. You can find more information on Shoes here.

Objective: To build a teeny-weeny mp3 player.

Step 1: Let us first download Shoes. We shall be using stable build file shoes-0.r396-curious.exe.

Step 2: Next, we start writing the code for our teeny-weeny mp3 player. To begin with, we just have 6 lines of code but which provides enough functionality.

#my_mp3player01.rb
Shoes.app do
  button( 'play' ){ @v.play }
  button( 'pause' ){ @v.pause }
  button( 'stop' ){ @v.stop }
  @v = video "C:/rubyprograms/mp3player/ruby.mp3"
end

On Windows, run Shoes from your Start Menu. Enter the C:/rubyprograms/mp3player folder and select my_mp3player01.rb. A screen pops up:

Screen 1

Now click on play. That’s it!

A Shoes application is simply a Ruby block: Shoes.app{ … } The Shoes.app part means “open the main Shoes window.” Inside the block, we describe what’s inside the window. Let’s add three buttons to our application that when pressed play/pause/stop our MP3. The last statement uses the video method to setup a Shoes::Video object. Shoes supports embedding of QuickTime, Flash video (FLV), DivX, Xvid and various other popular video formats, and some audio formats such as MP3, WAV and Ogg Vorbis. For more information, open the built-in Manual and read Elements Video section.

Step 3: Change Window size. Add background colors and caption.

# my_mp3player02.rb
Shoes.app :width => 300, :height =>165 do
  background green
  background rgb(255,208,208), :radius => 24
  caption 'My original tiny MP3 player!'

  button( 'play' ){ @v.play }
  button( 'pause' ){ @v.pause }
  button( 'stop' ){ @v.stop }
  @v = video "C:/rubyprograms/mp3player/ruby.mp3"
end

We have added just three more lines. The background method draws a Background element with a specific color, gradient or image. Shoes backgrounds are actual elements, not styles. Hence Shoes layers background elements. It’s not the same as HTML. For more information, open the built-in Manual and read Slots Element section. Also see “Nobody Knows Shoes (NKS)” - Backgrounds & Borders and Smooth Corner Cuts.

Screen 2

The caption method is one of the TEXT BLOCKS. Try to run the following sample code:

# textsize.rb
Shoes.app do
  banner "Banner\n"
  title "Title\n"
  subtitle "Subtitle\n"
  tagline "Tagline\n"
  caption "Caption\n"
  para "Para\n"
  inscription "Inscription\n"
  para "Specific font size", :size => 48
end

For more information, see NKS - the 1st chapter of 10 essentials.

Screen 2_1

Step 4: Oh! We need to layout the elements.

# my_mp3player03.rb
Shoes.app :width => 300, :height =>165 do
  background green
  background rgb(255,208,208), :radius => 24
  caption 'My original tiny MP3 player!'

  flow :left => 0, :top => 120  do
    button( 'play' ){ @v.play }

    button( 'pause' ){ @v.pause }
    button( 'stop' ){ @v.stop }
    @v = video "C:/rubyprograms/mp3player/ruby.mp3"
  end
end

In this case, we can use flow{ … } Shoes has a fundamental concept: stacks and flows. We need to understand the concept completely for layouting elements inside the window. Read this page carefully.

Screen 3

Now try to run the above program - my_mp3player03.rb by replacing the word ‘flow’ to ’stack’ and see the result (shown below).

Screen 3_1

Step 5: Want to listen other mp3 files?

# my_mp3player04.rb
Shoes.app :width => 300, :height =>165 do
  background green
  background rgb(255,208,208), :radius => 24
  caption 'My original tiny MP3 player!'

  flow :left => 0, :top => 120  do
    button( 'select?' ){@v = video ask_open_file}
    button( 'play' ){ @v.play }
    button( 'pause' ){ @v.pause }
    button( 'stop' ){ @v.stop }
  end
end

We can use built-in methods (also called: Kernel methods.) In this case, we can use ask_open_file method which pops up an ‘Open file…’ window.

Screen 4

For more information, see the built-in Manual for Built-in Methods section.

Step 6: Need to control select button depending on the situation.

# my_mp3player05.rb
Shoes.app :width => 300, :height =>165 do
  background green
  background rgb(255,208,208), :radius => 24
  caption 'My original tiny MP3 player!'

  flow :left => 0, :top => 120  do
    button 'select?' do
      tmp = @file
      (@v = video(@file)  unless (@file = ask_open_file).nil?)  if @file.nil? || !@v.playing?
      @file ||= tmp
    end
    button( 'play' ){ @v.play }
    button( 'pause' ){ @v.pause }
    button( 'stop' ){ @v.stop }
  end
end

As we write the program code, we need to consider several cases. Here, we have to handle the following cases:

  • if user doesn’t select the MP3 file yet
  • if the MP3 is playing
  • if the user pressed the cancel button on the select window

Screen 5

Step 7: Want to display mp3 file name and runtime per second?

# my_mp3player06.rb
Shoes.app :width => 300, :height =>165 do
  background green
  background rgb(255,208,208), :radius => 24
  caption 'My original tiny MP3 player!'

  stack :left => 0, :top => 70 do
    @l = para('', :stroke => white)
    animate do
      @l.replace strong "#{@file} : #{@v.time.to_i / 1000} sec"  unless @file.nil?
    end
  end

  flow :left => 0, :top => 120  do
    button 'select?' do
      tmp = @file
      (@v = video(@file)  unless (@file = ask_open_file).nil?)  if @file.nil? || !@v.playing?
      @file ||= tmp
    end
    button( 'play' ){ @v.play }
    button( 'pause' ){ @v.pause }
    button( 'stop' ){ @v.stop }
  end
end

To display the runtime per second, we can use the animate method: animate(fts){ … } The block will run fts times per second. fts is a option. If no number is given, default is 10.

For more information, see the built-in Manual: Slots Element section.

The para method sets up a Shoes::TextBlock object. In this case, it is assigned to @l. We can use the replace method in the block of the animate method to replace and redisplay the specific string such as the mp3 file name and the time position of the mp3. The time method shows the time position in milliseconds - so transform it into seconds.

Screen 6

Step 8: Want dancing loogink (Her (the creature) name) in the background while MP3 is playing?

# my_mp3player07.rb
$BASE_PATH = "C:/rubyprograms/mp3player/"

Shoes.app :width => 300, :height =>165 do
  background green
  background rgb(255,208,208), :radius => 24
  caption 'My original tiny MP3 player!'

  stack :left => 0, :top => 30 do
    @img = image $BASE_PATH + "loogink.png"
    n = 0
    animate(5) do
      @img.move( (n+=1) % 300 , 10 - rand(10))  if !@file.nil? && @v.playing?
    end
  end

  stack :left => 0, :top => 70 do
    @l = para('', :stroke => white)
    animate do
      @l.replace strong "#{@file} : #{@v.time.to_i / 1000} sec"  unless @file.nil?
    end
  end

  flow :left => 0, :top => 120  do
    button 'select?' do
      tmp = @file
      (@v = video(@file)  unless (@file = ask_open_file).nil?)  if @file.nil? || !@v.playing?
      @file ||= tmp
    end
    button( 'play' ){ @v.play }
    button( 'pause' ){ @v.pause }
    button( 'stop' ){ @v.stop }
  end
end

We can use the same structure of Step 7. The image method sets up a Shoes::Image object. In this case, it is assigned to @img. We can use the move method in the block of the animate method to move the object. For more information, see the built-in Manual: Elements Image section.

Screen 7

As you can see, if you know Ruby programming, you can easily learn Shoes to quickly build UIs. I’d like to take this opportunity to thanks Anita Kuno from Canada who created the oogink.png and ruby.mp3 files used in this blog post.

Conclusion: Some ideas to personalize this MP3 player:

  • use your favorite photo as a background
  • display the name of the song playing - You can learn how to extract the name of the song from a mp3 file in the excellent course conducted by Satish Talim at FORPC101

If you come up with any new idea, do write your original mp3 player and please do let me know. Have fun with Ruby!

Technorati Tags: , , , ,

Posted by Satish Talim

Tags: ····

7 responses so far ↓

  • 1 Willian Molinari // May 31, 2008 at 7:17 pm

    Æ!!

    Cool! The Satoshi’s article on Rubylearning Blog!
    I like this article because i can learn a bit of shoes, i want to write something with shoes, just waiting for the “Free time” =D.

    Congratulations Satoshi!
    Tks for share this article in your blog Satish!

    Cheers,

    Willian Molinari

  • 2 Satoshi Asakawa // Jun 1, 2008 at 6:09 am

    Thanks a lot, Willian!

    If you get interested in Shoes, try to run this teeny-weeny mp3 player. :)
    You can download all ruby source code, sample mp3 file, loogink image file and screenshots from the following URL:

    http://www.rin-shun.com/rubylearning/shoes/mp3player_src.zip

    Hava a happy programming!
    Satoshi

  • 3 Satoshi Asakawa // Jun 1, 2008 at 1:01 pm

    _why announced shoes 0.r646 for windows and linux in the shoes mailinglist today. And now still working for OS X.

    The latest distribution has some new good sample programs and revised built in manual. Let’s enjoy Ruby programming on Shoes. :)

    Satoshi

  • 4 Satoshi Asakawa // Jun 3, 2008 at 5:06 pm

    We can download Shoes-0.r646 from this:
    http://code.whytheluckystiff.net/shoes/wiki/RecentBuilds

    Shoes-0.r646 bundles a fantastic built-in manual.
    Use: shoes -m. Or Alt-Question-Mark on any Shoes app.

    Access the following URL that _why wrote about the manual.
    http://hackety.org/2008/05/31/desmalling.html

    Enjoy!
    Satoshi

  • 5 yhvd // Jun 3, 2008 at 5:34 pm

    Hmm. Would have been cuter without the scroll bar to the right.

  • 6 The Best of RubyFlow - Early June 2008 // Jun 17, 2008 at 5:41 am

    [...] an MP3 Player with Ruby and Shoes: Satoshi Asakawa has put together a cute tutorial demonstrating how to create a GUI-based MP3 player using Ruby and _why’s Shoes [...]

  • 7 kometbomb // Jul 2, 2008 at 11:54 pm

    This won’t make me want to hop on the Ruby bandwagon but nonetheless this looks impressive in it’s simplicity.

Leave a Comment