ruby/sdlで、無理やりyoutube 4

一時ファイル無しで、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