A Teeny-weeny mp3 player using Ruby and Shoes

By Satoshi Asakawa

Satoshi AsakawaSatoshi Asakawa is a Japanese Ruby enthusiast, a former student and now a Patron 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.

<span style="color:blue">#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</span>

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.

<span style="color:blue"># 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</span>

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:

<span style="color:blue"># 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</span>

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

Screen 2_1

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

<span style="color:blue"># 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</span>

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?

<span style="color:blue"># 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</span>

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.

<span style="color:blue"># 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</span>

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?

<span style="color:blue"># 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</span>

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?

<span style="color:blue"># 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</span>

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: , , , ,

comments powered by Disqus