<   2011年 06月 ( 11 )   > この月の画像一覧

このブログで、かなり書き散らしちゃいました。
ちょっと、整理を兼ねて、引っ越します。
このブログだと、
OPEN()
を、半角で書くとHTMLが使えなくなります。
それと、プログラムの前にスペースが入れれないので、
読みづらいですね。
FlashのActionScriptにも、ちょっと手を出してみました。
rubyの書き方と比べながら書いてみます。
こちらが、引越し先です。
[PR]
by gaziya | 2011-06-26 23:31
このタイトルも6回目。
きっと、これで終われると思う。

ruby/IOで標準入力が、大きい時は、
IO#syswrite(string)で、良さそうだ。
いっそのこと、全てのパターンで使ってやれ!?
output = ""
IO.popen("command", "r+") do |io|
io.syswrite(input)
io.close_write
output = io.read
end
かなり遠回りしたかな。

#!usr/bin/env ruby

require 'sdl'
require "stringio"

url = "http://www.youtube.com/watch?v=Bsk2ioK0Lrg"
system("youtube-dl #{url} -o /tmp/dl.flv")
flv = `cat /tmp/dl.flv`
duration = ""
IO.popen("ffmpeg -i - 2>&1", "r+") do |io|
io.syswrite(flv)
io.close_write
if /Duration: (\d{2}):(\d{2}):(\d{2}).(\d{1})/ =~ io.read
value = (($1.to_i * 60 + $2.to_i) * 60 + $3.to_i) * 10 + $4.to_i
duration = value * 0.1
end
end
SDL.init(SDL::INIT_VIDEO|SDL::INIT_AUDIO)
SDL::Mixer.open
IO.popen("ffmpeg -i - -f wav - | lame - /tmp/out.mp3", "w") do |io|
io.syswrite(flv)
end
bgm = SDL::Mixer::Music.load("/tmp/out.mp3")
IO.popen("ffmpeg -ss 0 -vframes 1 -i - -f image2 - 2> /dev/null", "r+") do |io|
io.syswrite(flv)
io.close_write
StringIO.open(io.read){|s| @surface = SDL::Surface.loadFromIO(s)}
end
screen = SDL::Screen.open(@surface.w, @surface.h, 32, 0)
SDL::Mixer.play_music(bgm, 1)
ticks = 0.1
s_ticks = SDL.get_ticks * 0.001
while ticks < duration
while e=SDL::Event.poll
exit if e.kind_of?(SDL::Event::Quit) || (e.kind_of?(SDL::Event::KeyDown) && e.sym == SDL::Key::ESCAPE)
end
IO.popen("ffmpeg -ss #{ticks} -vframes 1 -i - -f image2 - 2> /dev/null", "r+") do |io|
io.syswrite(flv)
io.close_write
StringIO.open(io.read){|s| @surface = SDL::Surface.loadFromIO(s)}
end
screen.put(@surface, 0, 0)
screen.flip
ticks = SDL.get_ticks * 0.001 - s_ticks
end
[PR]
by gaziya | 2011-06-16 21:57
他の方法も見つけたが、
gnuplotの出力をjpegにすると、最後の行で
``': string contains null byte (ArgumentError)
と、エラーを吐く。
image.classは、Stringだったのに。
手強すぎる。
今回の方法は、パイプの継ぎ方がわからなかった。

#!usr/bin/env ruby

eval = <<-EOF
set terminal svg
set output
plot sin(x)
EOF

image = `gnuplot <<EOF\n#{eval}`
`display <<EOF\n#{image}`
[PR]
by gaziya | 2011-06-15 22:20
rubyで外部コマンドの標準入力をするには、
IO.popenを使っている。
こんな感じ。

eval = <<-EOF
set terminal svg
set output
plot sin(x)
EOF

image = nil
IO.popen("gnuplot" ,"r+") do |io|
io.write(eval)
io.close_write
image = io.read
end
IO.popen("display" ,"w") do |io|
io.write(image)
end

これを、一つにまとめると

IO.popen("gnuplot | display" ,"w") do |io|
io.write(eval)
end

もう少し、短く書けないかな?ってことで
バッククウォートを使って

`echo '#{eval}' | gnuplot | display`

こう書けて、成功する。
だけど、これを分けて

image = `echo '#{eval}' | gnuplot`
`echo '#{image}' | display`

こうすると、
2行目でエラーになる。
どうも、echoの引数が長いみたい。
これが使えると、いいな。
[PR]
by gaziya | 2011-06-15 20:07
ここのところruby/ioと格闘していたら少し理解が上がった。
なので以前、書いた「Rをruby/ioで使う。」を焼き直してみたくなった。

#!usr/bin/env ruby

class R_IO
def initialize
@io = IO.popen("R -q --no-save", "r+")
end

def close
@io.puts("q()")
@io.close_write
@io.read
@io.close
end

def eval(cmd)
@io.puts(cmd)
@io.gets("\n")
#return @io.gets("> ")
return @io.gets("\n")
end
end

eval = <<-EOF
sqrt(2)
sqrt(3)
sqrt(5)
EOF

r = R_IO.new
eval.split("\n").each do |e|
puts r.eval(e)
end
r.close
[PR]
by gaziya | 2011-06-12 17:32
前回の奴の焼き直しだ。
fork,IO.pipe を使ってない。
ruby/IOの周辺は難しいですね。

ruby1.9でSDL::Surface.loadFromIO(io)を使えなかったので
sudo apt-get install libsdl-image1.2-dev
sudo gem1.9.1 install rubysdl
これで使えた。

<追記>
ruby/sdlで、無理やりyoutube 6 で、何とか恰好がついてます。
http://gaziya.exblog.jp/15773949/
こちらです。

#!usr/bin/env ruby

require 'sdl'
require "stringio"

url = "http://www.youtube.com/watch?v=Bsk2ioK0Lrg"
system("youtube-dl #{url} -o /tmp/dl.flv")
flv = `cat /tmp/dl.flv`
info = `ffmpeg -i /tmp/dl.flv 2>&1`
duration = ""
if /Duration: (\d{2}):(\d{2}):(\d{2}).(\d{1})/ =~ info
value = (($1.to_i * 60 + $2.to_i) * 60 + $3.to_i) * 10 + $4.to_i
duration = value * 0.1
end

SDL.init(SDL::INIT_VIDEO|SDL::INIT_AUDIO)
SDL::Mixer.open
system("ffmpeg -i /tmp/dl.flv -f wav - | lame - /tmp/out.mp3")
@bgm = SDL::Mixer::Music.load("/tmp/out.mp3")
IO.popen("ffmpeg -ss 0 -vframes 1 -i - -f image2 - 2> /dev/null", "r+") do |io|
begin
io.write(flv)
rescue
ensure
io.close_write
StringIO.open(io.read){|s| @surface = SDL::Surface.loadFromIO(s)}
end
end
screen = SDL::Screen.open(@surface.w, @surface.h, 32, 0)
SDL::Mixer.play_music(@bgm, 1)
ticks = 0.1
s_ticks = SDL.get_ticks * 0.001
while ticks < duration
while e=SDL::Event.poll
exit if e.kind_of?(SDL::Event::Quit) || (e.kind_of?(SDL::Event::KeyDown) && e.sym == SDL::Key::ESCAPE)
end
IO.popen("ffmpeg -ss #{ticks} -vframes 1 -i - -f image2 - 2> /dev/null", "r+") do |io|
begin
io.write(flv)
rescue
ensure
io.close_write
StringIO.open(io.read){|s| @surface = SDL::Surface.loadFromIO(s)}
end
end
screen.put(@surface, 0, 0)
screen.flip
ticks = SDL.get_ticks * 0.001 - s_ticks
end
[PR]
by gaziya | 2011-06-11 15:58
一時ファイル無しで、ruby/sdlで無理やりyoutubeだ。
と、始めたはいいが、ffmpegをruby/IOで使うには、かなり悩んだ。
ffmpegはコマンドが正常終了しても情報を標準エラーに出力するからだろうか?
IO.pipe,fork,例外処理,バッククォートを組み合わせて、なんとか使えるようになったが、
ruby/sdlと組み合わせると、今度はXwindowのエラーが出る。
もう、お手上げだ。
参考までにプログラム中の
exec("ffmpeg #{options}")

puts `ffmpeg #{options}`
すると、他のオプションも使える。かなり無理やりではありますが・・・。
映像ファイルから、画像データを一時ファイル無しで出来るから、その部分は載せておきます。
途中から、映像が遅れます。
やはり、無理がありますか。
映像ファイルとの相性があるらしく見れないのもある。
音声は、mp3を使ったので
sudo apt-get install lame
で、lameをいれてください。
あと、
sudo apt-get install libsdl-mixer1.2-dev
sudo gem1.9.1 install rubysdl
これで、SDL::Mixerが使える。

余談だが、映像ファイル関係の小ネタを一つ。
asxファイルから映像をダウンロードする方法。
asxファイルをwgetで拾ってきて、asxファイル(テキスト)を読むと mms://xxxというアドレスが書かれている。
それを、mimmsでダウンロードする。mimmsは、
sudo apt-get install mimms
でインストール。

<追記>
ruby/sdlで、無理やりyoutube 6 で、何とか恰好がついてます。
http://gaziya.exblog.jp/15773949/
こちらです。


#!usr/bin/env ruby

require 'sdl'
require "stringio"

class FFmpegIO
def initialize(movie_data)
@data = movie_data
end

def gets(options)
from_p, to_c = IO.pipe
from_c, to_p = IO.pipe
fork do
to_c.close
from_c.close
STDIN.reopen(from_p)
STDOUT.reopen(to_p)
exec("ffmpeg #{options}")
#puts `ffmpeg #{options}`
end
from_p.close
to_p.close
begin
to_c.puts(@data)
rescue
ensure
to_c.close
@result = from_c.read
from_c.close
end
@result
end

def bmp(ss)
image = self.gets("-ss #{ss} -vframes 1 -i - -f image2 - 2> /dev/null")
IO.popen("convert - bmp:-", "r+") do |io|
io.write(image)
io.close_write
@ret = io.read
end
@ret
end
end

url = "http://www.youtube.com/watch?v=Bsk2ioK0Lrg"
system("youtube-dl #{url} -o /tmp/dl.flv")
flv = `cat /tmp/dl.flv`
info = `cat /tmp/dl.flv | ffmpeg -i - 2>&1`
system("cat /tmp/dl.flv | ffmpeg -i - -f wav - | lame - /tmp/out.mp3")
duration = ""
if /Duration: (\d{2}):(\d{2}):(\d{2}).(\d{1})/ =~ info
value = (($1.to_i * 60 + $2.to_i) * 60 + $3.to_i) * 10 + $4.to_i
duration = value * 0.1
end

SDL.init(SDL::INIT_VIDEO|SDL::INIT_AUDIO)
SDL::Mixer.open
ffmpeg = FFmpegIO.new(flv)
@bgm = SDL::Mixer::Music.load("/tmp/out.mp3")
#@bgm = SDL::Mixer::Music.load_from_string(`cat /tmp/out.mp3`)
StringIO.open(ffmpeg.bmp(0)){|s| @surface = SDL::Surface.load_bmp_from_io(s)}
screen = SDL::Screen.open(@surface.w, @surface.h, 32, 0)
SDL::Mixer.play_music(@bgm, 1)
ticks = 0.1
s_ticks = SDL.get_ticks * 0.001
while ticks < duration
while e=SDL::Event.poll
exit if e.kind_of?(SDL::Event::Quit) || (e.kind_of?(SDL::Event::KeyDown) && e.sym == SDL::Key::ESCAPE)
end
StringIO.open(ffmpeg.bmp(ticks)){|s| @surface = SDL::Surface.load_bmp_from_io(s)}
screen.put(@surface, 0, 0)
screen.flip
ticks = SDL.get_ticks * 0.001 - s_ticks
end
[PR]
by gaziya | 2011-06-11 13:16
rmagickからrcairoへのデータの受け渡しで、またバグが発生した。
まあ、逃げ道が、あるからいいけど。
そんなことで、今度は、rcairoでやってみた。
おばちゃん軍団を一体のボスキャラに見立ててみようと、目論んだ。


#!usr/bin/env ruby

require 'sdl'
require 'cairo'

class BackGround
def initialize(w, h)
@w, @h = w, h
end

def update(c)
c.set_source_color(:black)
c.rectangle(0, 0, @w, @h)
c.fill
end
end

class Ball
def initialize(w, h)
@x, @y = w / 2, h / 2
system("youtube-dl 'http://www.youtube.com/watch?v=83P8xRIG3eI' -o /tmp/0.flv")
@ptn = []
(2.1 .. 4.4).step(0.05) do |t|
system("ffmpeg -ss #{t} -vframes 1 -i /tmp/0.flv -f image2 /tmp/0.png 2> /dev/null")
sn = Cairo::ImageSurface.from_png("/tmp/0.png")
image = Cairo::ImageSurface.new(260, 230)
cr = Cairo::Context.new(image)
cr.matrix = Cairo::Matrix.translate(-100, 0)
cr.set_source(sn)
cr.paint
@ptn << image
end
@w, @h = @ptn.first.width, @ptn.first.height
@image = Cairo::ImageSurface.new(@w, @h)
@erx = @w / 2 .. w - @w / 2
@vx= 2
@vx *= -1 if rand(9) < 5
@cut = 0
end

def update(c)
sn = Cairo::Context.new(@image)
sn.set_source(@ptn[@cut])
sn.circle(@w / 2, @h / 2 ,@w / 2 - 10)
sn.fill
@cut += 1
@cut = 0 if @cut == @ptn.size
@vx *= -1 if !@erx.include?(@x + @vx)
@x += @vx
c.matrix = Cairo::Matrix.translate(@x -@w / 2, @y - @h / 2)
c.set_source(@image)
c.paint
end
end

class Phase
def initialize(screen)
@screen = screen
@w, @h = @screen.w, @screen.h
@image = Cairo::ImageSurface.new(@w, @h)
@bg = BackGround.new(@w, @h)
@ball = Ball.new(@w, @h)
end

def update
context = Cairo::Context.new(@image)
@bg.update(context)
@ball.update(context)
surface = SDL::Surface.new_from(@image.data, @image.width, @image.height, 32, @image.stride, 0, 0, 0, 0)
@screen.put(surface, 0, 0)
end

def run
loop do
while e=SDL::Event.poll
exit if e.kind_of?(SDL::Event::Quit) || (e.kind_of?(SDL::Event::KeyDown) && e.sym == SDL::Key::ESCAPE)
end
self.update
@screen.flip
SDL.delay(30)
end
end
end

SDL.init(SDL::INIT_VIDEO)
@screen = SDL::Screen.open(650, 450, SDL::Screen.info.bpp, SDL::SWSURFACE)
Phase.new(@screen).run
[PR]
by gaziya | 2011-06-05 11:49
ImageMagickで加工をしました。
色々できそうです。


#!usr/bin/env ruby

require 'sdl'
require 'RMagick'

SDL.init(SDL::INIT_VIDEO)
screen = SDL::Screen.open(250, 250, 32, 0)
system("youtube-dl 'http://www.youtube.com/watch?v=83P8xRIG3eI' -o /tmp/0.flv")
items = []
(0.2 .. 5.3).step(0.05) do |t|
system("ffmpeg -ss #{t} -vframes 1 -i /tmp/0.flv -f image2 /tmp/0.jpg 2> /dev/null")
magick = Magick::Image.read("/tmp/0.jpg").first
magick = magick.crop(100, 0, 290, 250)
magick = magick.scale(250, 250)
magick = magick.equalize
pixels = magick.export_pixels_to_str(0, 0, magick.columns, magick.rows, 'BGRA')
items << SDL::Surface.new_from(pixels, magick.columns, magick.rows, 32, pixels.size / magick.rows, 0, 0, 0, 0)
#screen.put(items.last, 0, 0)
#screen.flip
end
i = 0
loop do
while e=SDL::Event.poll
exit if e.kind_of?(SDL::Event::Quit) || (e.kind_of?(SDL::Event::KeyDown) && e.sym == SDL::Key::ESCAPE)
end
screen.put(items[i], 0, 0)
screen.flip
SDL.delay(30)
i += 1
i = 0 if i == items.size
end
[PR]
by gaziya | 2011-06-04 15:41
前回、SDL::MPEGで失敗
違う方法を探してみた。
ffmpegでコマを抜き出してruby/sdlで表示させた。
まあ、最初は、こんなもんだろう。
サンプルは、youtubeからもらった。
sudo apt-get install youtube-dl
これで、簡単にyoutubueから映像を拾ってこれる。
あと ffmpegは
sudo apt-get install ffmpeg
です。
今回のプログラム、”おばちゃん最高!”


#!usr/bin/env ruby

require 'sdl'

SDL.init(SDL::INIT_VIDEO|SDL::INIT_AUDIO)
screen = SDL::Screen.open(500, 300, 32, 0)
system("youtube-dl 'http://www.youtube.com/watch?v=83P8xRIG3eI' -o /tmp/0.flv")
items = []
(0.2 .. 5.3).step(0.05) do |t|
system("ffmpeg -ss #{t} -vframes 1 -i /tmp/0.flv -f image2 /tmp/0.bmp 2> /dev/null")
items << SDL::Surface.load_bmp("/tmp/0.bmp")
end
i = 0
loop do
while e=SDL::Event.poll
exit if e.kind_of?(SDL::Event::Quit) || (e.kind_of?(SDL::Event::KeyDown) && e.sym == SDL::Key::ESCAPE)
end
screen.put(items[i], 0, 0)
screen.flip
SDL.delay(30)
i += 1
i = 0 if i == items.size
end
[PR]
by gaziya | 2011-06-04 09:51