A Teeny-weeny mp3 player using Ruby and Shoes
31/May 2008
By Satoshi Asakawa
Satoshi 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:
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.
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.
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.
Now try to run the above program – my_mp3player03.rb by replacing the word ‘flow’ to ‘stack’ and see the result (shown below).
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.
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
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.
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.
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: mp3 Player, Japan, Ruby on Shoes, Ruby Programming, Satoshi Asakawa