неділя, 25 січня 2009 р.

C or Do [mpd + icecast]

Налаштування Icecast описується у попередній статті.

Встановлення і налаштування mpd

Для інсталяції просто виконуємо наступну команду:
sudo apt-get install mpd

Робимо деякі зміни у файлі /etc/mpd.conf
######################## REQUIRED PATHS ########################
# You can put symlinks in here, if you like. Make sure that
# the user that mpd runs as (see the 'user' config parameter)
# can read the files in this directory.
music_directory "/media/sda9/music"
playlist_directory "/var/lib/mpd/playlists"
db_file "/var/lib/mpd/tag_cache"
log_file "/var/log/mpd/mpd.log"
error_file "/var/log/mpd/errors.log"
pid_file "/var/run/mpd/pid"
################################################################

Тут:
"music_directory" - каталог з музичними файлами, з яких потім будуть складатися програми.
"playlist_directory" - каталог, у якому mpd буде зберігати свої плей-листи.
"db_file" - файл, у якому mpd буде зберігати свою медіа-бібліотеку.
"log_file" і "error_file" - файли логів.

Далі потрібно налаштувати вивід звуку через Icecast:
# An example of a shout output (for streaming to Icecast):
#
audio_output {
type "shout"
name "My Shout Stream"
host "localhost"
port "8000"
mount "/mpd.ogg"
password "password1"
# quality "5.0"
bitrate "128"
format "44100:16:1"
user "password1" # optional
description "My Stream Description" # optional
genre "rock" # optional
public "no" # optional
}

Тут:
Параметри "host", "port" і "password" описують з'єднання з icecast.
Параметри "bitrate" і "format" задають якість потоку.

Кодування файлової системы і тегів в mp3-файлах:
filesystem_charset              "UTF-8"       
id3v1_encoding "CP1251"
Інші параметри можна залишити по замовчуванню.

На цьому настройка закінчена. Теперь потрібно проіндексувати каталог з музикою і запустити сервіси:
sudo mpd --create-db                                                                             
sudo /etc/init.d/icecast start
sudo /etc/init.d/mpd start

Зверніть увагу не те, що mpd обов'язково повинен стартувати після icecast.

Для керування програванням можна скористатися одним із клієнтів.
Використаємо консольний клієнт mpc
sudo apt-get install mpc

Додамо у плейлист всю базу пісень і запустимо програвання у довільному порядку
mpc add /                                                                   
mpc random on
mpc play

Після чого можете налаштувати ваш улюблений плеєр(я використовую Audacious) на програвання ogg-потоку з адреси http://<ваш_IP>:8000/mpd.ogg.

Бага

Я помітив, що mpd після зупинки/паузи, не реагує на команду play.
У файл логів /var/log/mpd/errors.log записуються наступні помилки:
[...]                                                           
Jan 25 15:01 : problems opening audio device while playing "world/n/Neversmile/2006.Миллиарды Минут/05-V_Otkrytuiu_Ranu.mp3"
Jan 25 15:01 : problems opening audio device while playing "world/b/Bloc Party/2008. Intimacy/08 - Zepherus.ogg"
Jan 25 15:02 : problems opening audio device while playing "world/а/Андерсон/2008.Словозброя/03 Споживач.ogg"
[...]


Недовгий пошук у гуглі привів до вирішення цієї проблеми.
https://bugs.launchpad.net/ubuntu/+source/mpd/+bug/155932
Якщо додати наступні рядки у /etc/mpd.conf, проблема зникає.

audio_output {
type "ao"
driver "null"
name "Dummy output"
}

$ cat /etc/issue
Ubuntu 8.10

$ uname -a
Linux linux 2.6.27-9-generic #1 SMP Thu Nov 20 21:57:00 UTC 2008 i686 GNU/Linux

$ mpd --version
mpd (MPD: Music Player Daemon) 0.13.2

Copyright (C) 2003-2007 Warren Dukes <warren.dukes@gmail.com>
This is free software; see the source for copying conditions. There is NO
warranty; not even MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Supported formats:
mp3 mp2 ogg oga ogg flac wav au aiff aif m4a mp4 mpc amf dsm far gdm imf it med mod mtm s3m stm stx ult uni xm

Supported outputs:
alsa ao oss pulse shout jack

Можливо в інших версія ця проблема відсутня.

Q: А до чого тут Ruby?
A: вам сюди http://librmpd.rubyforge.org
Інсталяції здійснюється командою:
sudo gem install librmpd

В архіві з librmpd у каталозі exampes є 2 досить хороших приклади роботи з mpd засобами ruby.
Більш детально про librmpd я розповім у одному з наступних дописів.

четвер, 22 січня 2009 р.

Icecast2 + ruby-shout

Icecast — вільне програмне забезпечення для організації потокового цифрового аудіомовлення. Його підтримкою займається Xiph.org Foundation.
Icecast є серверною програмою, яка може здійснювати роздачу цифрових потоків різних форматів, таких як Ogg Vorbis, Mp3, Theora, ААС, Aacplus і NSV. Власне передача даних здійснюється по стандартному протоколу HTTP, або по протоколу Shoutcast.
Icecast є аналогом програми Shoutcast компанії Nullsoft, проте має розвиненішу функціональність і підтримує більшу кількість форматів потоків. При передачі даних Icecast підтримує теги в Utf-8, що дозволяє організовувати трансляцію з кириличною анотацією.

Встановлення і налаштування Icecast2


Для встановлення Icecast2 просто запускаємо:
$ sudo apt-get install icecast2

Після цього ми повинні змінити /etc/icecast2/icecast.xml. Більшість значень по замовчуванню повинні працювати, але ви повині змінити паролі у секції <authentication>...</authentication>.

  • source-password це пароль який наша програма у майбутньому буле використовувати для зв'язку з сервером Icecast2;

  • admin-password це пароль який адміністратор буде використовувати у веб-інтерфейсі  Icecast2;

  • relay-password ми не будемо використовувати, але так чи інакше ви повинні змінити його.


[...]                              
<authentication>
<!-- Sources log in with username 'source' -->
<source-password>password1</source-password>
<!-- Relays log in username 'relay' -->
<relay-password>password2</relay-password>

<!-- Admin logs in with the username given below -->
<admin-user>admin</admin-user>
<admin-password>password3</admin-password>
</authentication>
[...]

Далі редагуємо /etc/default/icecast2 і встановлюємо ENABLE як true
[...]                                                      
ENABLE=true
[...]

Запускаємо сервер Icecast2:
$ sudo /etc/init.d/icecast2 start


Зараз ви можете у веб-броузері перейти за адресою http://127.0.0.1:8000/ і подивитись на веб-інтерфейс:


Встановлення ruby-shout


Встановлюємо пакети необхідні для ruby-shout:
$ sudo apt-get install libogg-dev libshout3-dev libspeex-dev libtheora-dev libvorbis-dev


libshout - це бібліотека для трансляції аудіо до icecast або shoutcast-сумісних серверів. На даний момент вона відтримує 2 формати аудіо і 3 протоколи.

Формати аудіо:

  • Ogg Vorbis

  • MP3



Протоколи:

  • HTTP

  • Audiocast

  • ShoutCast



ruby-shout це інтерфейс Ruby до libshout. Він дозволяє програмам на Ruby легко відправляти дані до icecast сервера і управляти мета-інформацією про потік.

Для інсталяції ruby-shout просто виконуємо:
$ sudo gem install ruby-shout


Приклад


Скрипт зчитує звукові дані з вхідного файлу і відправляє їх icecast серверу без resampling.
#!/usr/bin/ruby                  

# Stream all the files given on the commandline to the Icecast server on
# localhost.

require 'rubygems'
require 'shout'

BLOCKSIZE = 16384

s = Shout.new
s.host = "localhost"
s.port = 8000
s.mount = "/example.ogg"
s.format = Shout::VORBIS
s.user = "source"
s.pass = "password1"
s.name = "Example Radio"
s.description = "Powered by Ruby/#{VERSION}, ruby-shout/#{Shout::version}"
s.genre = "Rock"

s.connect

ARGV.each do |filename|
File.open(filename) do |file|
puts "sending data from #{filename}"
m = ShoutMetadata.new
m.add 'filename', filename
s.metadata = m
while data = file.read(BLOCKSIZE)
s.send data
s.sync
end
end
end

s.disconnect


Посилання


неділя, 18 січня 2009 р.

I'm alive! - 2


Цей пост від свого попередника відрізняється хіба що фоткою :). Всіх з Новим 2009 Роком!

P.S. У зв'язку з тим, що сайт infostore був закритий всі посилання на книжки, які я раніше викладав у цьому блозі були втрачені :(.


P.P.S. Документацію і книги по Ruby on Rails а також веб технологіям можна скачати з RubyClub.ua.

субота, 17 січня 2009 р.

Mechanize + вКонтакте

Цей допис несе навчально-практичний характер. На прикладі бібліотеки Mechanize я продемонструю як просто можна серфити веб-сторінками.
наш простий скрипт буде виконувати наступні дії:

  • Авторизація на сайті ВКонтакте

  • Зчитування кількості нових повідомлень і фотографій


І все це без використання веб-броузера.
Далі трохи теорії.

Mechanize використовується для автоматизації взаємодії з веб-вузлами. Mechanize автоматично запам'ятовує і відсилає куки(cookies), слідує за перенаправленнями(redirects), може переходити по лінках. Може використовуватись для заповнення форм. Крім того Mechanize тримає в історії список сайтів, які ви відвідали.
А для синтаксичного розбору html використовує nokogiri.

А тепер власне сам скрипт. У якості параметрів він приймає е-мейл і пароль. На виході - кількість нових фотографій і повідомлень. Крім того у скрипті передбачена реакція на невірний логін/пароль.
Це лише невелий приклад і можливість розширення обмежується тільки вашою фантазією.

require "rubygems"                                                          
require "mechanize"

$KCODE = "UTF8"

a = WWW::Mechanize.new {|agent|
# WWW::Mechanize::AGENT_ALIASES
agent.user_agent_alias = 'Linux Konqueror'
# VKontakte refresh after login
agent.follow_meta_refresh = true
}

a.get('http://vkontakte.ru/') do |home_page|
# home_page.links.each{|link| puts link.text}
# home_page.forms.each{|form| puts form.name}
singin_page = a.click(home_page.links_with(:text => 'Login').first)
my_page = singin_page.form_with(:name => 'login') do |form|
form.email = ARGV[0]
form.pass = ARGV[1]
end.submit
if my_page.title == 'VKontakte | Login'
puts "Such an e-mail address is not registered or an incorrect password is entered"
end
#pp my_page

# <div id="sideBar">
# <ol id='nav'>
# <li><a href='mail.php?id=13327146&41867'>My Messages</a></li>
# </ol>
# </div>
#
# Mix and match
messages = my_page.search('div.ol.li.a', '//div[@id="sideBar"]/ol[@id="nav"]/li/a').each do |link|
case link.content
when /My Messages/
messages = link.content.match(/^(My Messages)($)?( \((\d+)\)$)?/)[4] || 0
puts "Messages: #{messages}"
when /My Photos/
photos = link.content.match(/^(My Photos)($)?( \((\d+)\)$)?/)[4] || 0
puts "Photos: #{photos}"
end
end
end