drewish / textFlow

Ruby script to convert iTunes album art into ASCII

This URL has Read+Write access

textFlow / textFlow.rb
100755 121 lines (107 sloc) 3.844 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#!/usr/bin/env ruby
 
# Copyright 2008, 2009 Andrew Morton <drewish@katherinehouse.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
 
 
# This script requires the appscript and ncurses libraries.
# To install it run: sudo gem install rb-appscript ncurses
#
# You'll also need to have ImageMagick and jp2a installed.
# Use MacPorts: sudo port install jp2a imagemagick
 
begin;
  require 'rubygems'
  require 'osax'
  require 'appscript'
  require 'ncurses'
  rescue LoadError;
end
include Appscript
include OSAX
 
begin
  # initialize ncurses
  Ncurses.initscr
  Ncurses.cbreak # provide unbuffered input
  Ncurses.noecho # turn off input echoing
  Ncurses.nonl # turn off newline translation
 
  Ncurses.stdscr.intrflush(false) # turn off flush-on-interrupt
  Ncurses.stdscr.keypad(true) # turn on keypad mode
 
  Ncurses.stdscr.mvaddstr(0, 0, 'Loading iTunes...')
  it = app('iTunes')
  Ncurses.stdscr.mvaddstr(1, 0, 'Reading first track...')
 
  # If iTunes hasn't played anything since starting then current_track won't be
  # defined. To avoid this we can start and the stop the player.
  if it.player_state.get == :stopped
    it.play
    it.pause
  end
  lastTrackId = nil
 
  # Main loop.
  begin
    artWidth = 0
    begin
      # Check if the track has changed and update the display.
      if lastTrackId != it.current_track.database_ID.get
        lastTrackId = it.current_track.database_ID.get
        Ncurses.stdscr.clear
 
        # Convert the album art into ascii and dump it to the screen.
        if it.current_track.artworks.get.length > 0
          cmd = 'convert - -contrast-stretch 5%x2% jpg:- | jp2a --height=' + (Ncurses.LINES()).to_s + ' -'
          IO.popen(cmd, 'r+') do |pipe|
            pipe << it.current_track.artworks.first.get.raw_data.get.data
            pipe.close_write
            ascii = pipe.readlines
            ascii.each_index {|i|
              Ncurses.stdscr.mvaddstr(i, 0, ascii[i])
            }
            artWidth = ascii.first.length
          end
        end
 
        Ncurses.stdscr.mvaddstr(Ncurses.LINES() / 2 + 0, artWidth + 2, it.current_track.artist.get)
        Ncurses.stdscr.mvaddstr(Ncurses.LINES() / 2 + 1, artWidth + 2, it.current_track.name.get)
        Ncurses.refresh
      end
    # Generally the CommandError is thrown when there's not a current track.
    rescue CommandError
      Ncurses.stdscr.clear
      Ncurses.stdscr.mvaddstr(Ncurses.LINES() / 2, artWidth + 2, 'Nothing playing.')
      Ncurses.refresh
      lastTrackId = nil
    end
 
    # Wait for keyboard input for half a second then give up so we can check
    # if the track has changed.
    if IO.select([STDIN], nil, nil, 0.5)
      ch = Ncurses.stdscr.getch()
      case(ch)
      when ?\ :
        it.playpause
      when Ncurses::KEY_RIGHT :
        it.next_track
      when Ncurses::KEY_LEFT :
        it.previous_track
      when Ncurses::KEY_UP :
        osax.set_volume(:output_volume => 100)
      when Ncurses::KEY_DOWN :
        osax.set_volume(:output_volume => 0)
      when 'q'[0], 'Q'[0] :
        exit
  # else
  # Ncurses.stdscr.mvaddstr(3, 0, ch.to_s)
      end
    end
  end while true
 
ensure
  Ncurses.echo
  Ncurses.nocbreak
  Ncurses.nl
  Ncurses.endwin
end