Blog
Experiment #2: Lego NXT als Fernbedienung
Ich sitze nun oft auf meinem Bettsofa und möchte auf einen anderen Sender meines TV-Streams, der wie in Experiment #1 aufgebaut ist, umschalten.
Da ich mir keinen Infrarotempfänger kaufen/basteln will, habe ich meinen NXT gezückt und ein Programm mit C# und NXC, einer Sprache für den NXT ähnlich zu C, geschrieben. Das ganze funktioniert über Bluetooth. Hier ist der C# Quelltext:
/* Öffnet eine Verbindung zur COM Verbindung /dev/rfcomm0
wie man eine Bluetooth Serialschnitstelle erstellen können Sie nachlesen:
http://juju.org/articles/2006/10/22/bluetooth-serial-port-to-nxt-in-linux
*/
btConnection.Open(); //Öffnet die Verbindung
while(true)
{
if(btConnection.BytesToRead >= 9) /* Wenn Bytes zum Lesen vorhanden sind,
hier 9 Bytes, weil meine Nachrichten immer
nur 9 Bytes lang sind. Da meist alle Bytes auf einmal
ankommen (schätze ich), kann man hier auch weniger
angeben */
{
byte[] buffer = new byte[btConnection.BytesToRead];
// Buffer für die zu empfangenden Bytes
btConnection.BaseStream.Read(buffer, 0, btConnection.BytesToRead);
// Hier werden die vorhandenen Bytes oder noch mehr in den buffer eingelesen
string recived = "";
// Dieser string wird die Nachricht enthalten
for(int i = 0; i < style="color: rgb(51, 102, 255);">/* Wenn das jetztige Byte ein 0 Zeichen enthält, wird das bis jetztige gelesene gelöscht, da dort nur Kontrollinfos sind (?). Nur der letze Inhalt, die Daten, werden behalten. Deshalb das 2.Statment im if */
recived = ""; //Löschen der gelesenen Daten
else
recived += Encoding.ASCII.GetString(new byte[] { buffer[i] });
/Ansonsten Zeichen hinzufügen
}
switch(recived.Substring(0, 3)) /* Nun überprüfen wir die Nachricht. Sehen Sie sich dazu das NXC Programm an */
{
case "CHN": //CHN soll channel bedeuten
Console.WriteLine("wechsle zu Sender " + recived.Substring(4)); /* todo, hier werde ich mit einer shh Bibliothek zu meinem
Server eine Verbindung herstellen, um den Sender mittels
v4lctl zu wechseln. */
break;
case "VOL": //VOL bedeuted volume
Console.WriteLine("Lautstärke: " + recived.Substring(4));
// todo
break;
default:
Console.WriteLine("unbekannter Befehl: " + recived.Substring(0, 3));
break;
}
}
Thread.Sleep(100);
//Dieses Programm ist noch nicht ausgereift :-)
string taskList[]; /*Hier sind Einträge wie "zu ORF1 wechseln" oder "zu SF2 wechseln" */
string command[]; /* Hier werden die tatsächlichen Befehle, die zum Computer gesendet werden */
void SendCommand(string command)
{
BluetoothWrite(0, command);
Wait(500); //Warten bis die Taste losgelassen wird.
}
void DrawMenu(int act) /* Zeichnen des Menüs, es ist ein einfaches Menü, dass in pro Zeile einen Befehl enthält. */
{
ClearScreen(); //Displayinhalt löschen
for(int i = 0; i < i ="=" style="color: rgb(51, 102, 255);">/*act ist die zur Zeit gewählte Aktion, diese wird weiter rechts geschrieben. */
TextOut(10, 56 - i * 8, taskList[i]); /* ich habe hier i * 8
geschrieben, da eine Zeile 8 Pixel hoch ist. 56 - i * 8, damit
das ganze am oberen Displayrand zu sehen ist. */
else
TextOut(0, 56 - i * 8, taskList[i]); //das ist ein normaler Eintrag
}
Wait(500); /* Diese Funktion wird meist aufgerufen, wenn eine Taste betätigt wurde, deshalb wird hier 500 ms gewartet */
}
task main()
{
ArrayBuild(taskList, "zu SF2 wechseln", "zu PRO7 wechseln",
"zu ORF1 wechseln", "channel RTL2", "raise volume");
//Dieser Array ist parallel zu dem command Array
ArrayBuild(command, "CHN SF2", "CHN PRO7", "CHN ORF1",
"CHN RTL2", "VOL UPP");
int active = 0; /* Das aktive Element, bei Programmstart ist das erste gewählt hier wäre das "zu SF2 wechseln" */
DrawMenu(active); //Das Menü zum ersten Mal anzeigen.
while(1)
{
if(ButtonPressed(BTNRIGHT, true) &&
(active + 1) < style="color: rgb(51, 102, 255);">/* Der rechte Button am NXT wurde gedrückt, deshalb wird, falls der Index des aktiven Menüelements + 1 noch ein gültiges Element im Menüarray ist, um 1 erhöht. */
{
active += 1;
DrawMenu(active); /* Da das aktive Menüelement
geändert wurde, muss das Menü neu gezeichnet werden. */ }
if(ButtonPressed(BTNLEFT, true) && (active - 1) >= 0) /* Der linke
Button vom NXT wurde gedrückt. Das heißt, dass wenn der
Index - 1nicht negativ ist, um 1 subtrahiert wird. */
{
active -= 1;
DrawMenu(active);
}
if(ButtonPressed(BTNCENTER, true)) /* Der mittlere Button,
auf dem NXT der orange, wurde gedrückt. Das heißt, dass
der dazugehörige Befehl zum aktiven Menüelement zum
Computer gesendet wird. */
SendCommand(command[active]);
}
}
Schlüsselwörter: C#,VLC,Mono,Lego NXT,
zuletzt geändert: 29. Juli 2007 21:49
Link zu diesem Artikel: (in die Zwischenablage)
Experiment #1: TV-Stream mit VLC
Dieses "Experiment" habe ich bereits fertiggestellt.
Ich habe es mit Debian GNU/Linux "etch" ausprobiert. Ich verwende VLC 0.8.6a.
#1: Module laden
Meine TV-Karte ist eine saa7134 (Philips) Medion. Jemand hat mir auch berichtet, dass die Terratec Cinergy 600 auch funktioniert. Das saa7134 Modul wurde bei mir schon automatisch geladen. Doch damit man später auch etwas hört, muss das Soundmodul geladen werden. Hier stehen die Module saa7134-oss oder saa7134-alsa zur Auswahl, die mit dem Befehl
"modprobe saa7134-oss" bzw. "modprobe saa7134-alsa"
geladen werden können. Bei mir funktionierte das saa7134-oss Modul besser als das alsa Modul. Damit das Modul beim Start geladen wird, kann man es einfach in die Datei /etc/modules schreiben (pro Zeile ein Modul).
#2: Wiedergabeliste
Eine Wiedergabeliste ist praktisch, damit man später im VLC Webinterface die Kanäle umschalten kann. Als Wiedergabeliste habe ich eine m3u verwendet:
#EXTM3U
#EXTINF:-1,ORF1
v4l:/dev/video0:norm=pal:size=640x480:channel=0:adev=/dev/
dsp1:
audio=0:frequency=224250
Hier kann man mit den Parametern experimentieren. Besonders die Parameter size, adev und frequency sind wichtig.
Bei dem size Argument kann man 320x280 oder andere Größen einfügen. Wichtig ist nur, dass das Argument im 4:3 Verhältnis bleibt: 640 / 4 * 3 = 480, oder 320 / 4 * 3 = 280. Ein 16:9 Verhältnis habe ich nicht ausprobiert.
Das Argument adev enthaltet die "virtuelle" Soundkarte von der TV-Karte. Man sieht welche Nummer diese Karte hat, wenn man das saa7134-oss/alsa Modul ladet.
Das wichtigste, die Frequenz, wird mit dem frequency Parameter gesetzt. 224.25 Mhz = 224250, 375.25 Mhz = 375250
Der channel Parameter gibt den Eingang ein: 0 = Television, 1 = Composite1, 2 = S-Video
dieses Nummern können je nach Karte anders sein. Man sieht sie indem man den Befehl "v4lctl -c /dev/video0 list" ausführt (xawtv muss installiert sein). Man sieht so auch andere Argumente wie volume. Man kann diese änderen durch den Befehl: v4lctl -c /dev/video0 volume 5
Für Attribute muss man anstatt dem Argument volume im vorigen Befehl setattr attributname wert (z.B.: v4lctl -c /dev/video0 setattr Mirror on.
Für jeden Kanal muss man einen Eintrag schreiben.
#EXTINF:-1,KANALNAME
v4l:/dev/video0:norm=pal:size=640x480:channel=0:adev=/dev/
dsp1:
audio=0:frequency=100250
#3: VLC starten
Natürlich könnte man auch den VLS (VideoLan Server) verwenden, doch dieses Projekt wurde abgebrochen.
Nun kann man VLC starten, um die Videoausgabe zu testen:
vlc /pfad/zu/den/wiedergabelisten/normal.m3u
Nun sollte (falls gegeben) auf dem Bildschirm der 1. Kanal laufen (in meinem Fall ORF1). Doch leider ist das noch kein Stream. Ich verwende für meinen TV-Stream den Videocodec mp4 mit dem Audiocodec mp2a, verkapselt in asfh mit dem mmsh Protokoll. Natürlich kann man diese Codecs sowie alle anderen Streamoptionen ändern. Eine Übersicht, wie man welchen Codec anwendet, kann man im Streaming guide auf der VideoLan Webseite ansehen:
http://www.videolan.org/doc/streaming-howto/en/streaming-howto-en.html
Nun würde der Befehl lauten:
vlc /pfad/zu/den/wiedergabelisten/normal.m3u --sout '#transcode{vcodec=mp4v,scale=1,ab=64,acodec=mp2a}:std{access=mmsh,mux=asfh,dst=:8050}'
Der Parameter --sout defieniert eine Ausgabe. Innerhalb dieses Parameters werden die Optionen festgelegt:
Der erste Vorgang wird mit einem # gekennzeichnet, andere mit mit einem : davon getrennt. Innerhalb von den geschwungengen Klammern von #transcode (= Daten von der TV-Karte konvertieren) können die Parameter angepasst werden:
vcodec setzt den Videocodec. Andere Codecs als mp4v wären DIV3 für den Windows Media Player. Mehrere Beispiele findet man im Streaming Guide auf der Videolan Webseite (Link oben angeführt)
scale definiert die Skalierung: 1 = bleibt 1:1 gleich. Es können hier auch Werte wie 0.2 oder 0.5 Angeführt werden.
ab bedeutet AudioBitrate. Normalerweise sollte diese höher sein, als hier angeführt.
Als letztens: acodec definiert den Audio Codec. Im Streaming Guide wird hier meistens mp3 angeführt. Doch in Debian ist VLC ohne MP3 Unterstützung komplimiert worden (Lizenz).
Innerhalb von den geschwungenen Klammern von :std werden die Streamingoptionen angegeben.
access ist das Protokoll, über das die Daten gesendet werden (z.B.: http oder udp ist möglich)
mux setzt die Verkapselungsmethode: hier asf
dst definiert die Adresse, auf der auf Verbindungen gehört wird. Natürlich kann man hier auch eine IP Adresse schreiben: 192.168.0.4:8050
Hier ist 8050 der Port, dieser kann natürlich auch geändert werden.
Fast fertig, fehlt nur noch das Umschalten über das Webinterface von VLC.
#4: Webinterface
das Webinterface wird durch die Parameter --http-host und -I http festgelegt:
vlc /pfad/zu/den/wiedergabelisten/normal.m3u --sout '#transcode{vcodec=mp4v,scale=1,ab=64,acodec=mp2a}:std{access=mmsh,mux=asfh,dst=:8050}' -I http --http-host :8055
Nun kann man seinen TV-Stream genießen. Ich habe für mich zwei weitere Wiedergabelisten tiny und PAL erstellt, in denen man seinen TV-Stream mit 320x280 Pixeln oder 720x576 Pixeln Auflösung streamen kann.
#5: Aufnehmen:
Mit diesem Befehl nehme ich meine Filme auf:
vlc /pfad/zu/den/wiedergabelisten/normal.m3u --sout "#transcode{vcodec=mp4v,acodec=mpga,ab=96,scale=1}:duplicate{dst=std{access=file,mux=asf,dst=/pfad/zum/video.wmv},dst=std{access=mmsh,mux=asfh,dst=:8050}}"
Hier habe ich absichtlich das Webinterface weggelassen. Mit access=file wird festgelegt, dass in eine Datei "gestreamt" wird. Mit dem duplicate kann man den Stream mehrmals verwenden.
#6: Probleme:
Kein Sound: Tut mir leid, dass ich das vergessen habe. Der Befehl "v4lctl volume mute off" muss ausgeführt werden. So wird der Sound eingeschaltet. Nach einem Neustart muss dieser Befehl nochmal ausgeführt werden. Dieses Programm ist im Paket "xawtv" enthalten.
gutes gelingen
Schlüsselwörter: VLC
zuletzt geändert: 16. Juli 2007 21:56
Link zu diesem Artikel: (in die Zwischenablage)
(c) 2003-2009 | Impressum| Empfehlenswerte Blog Einträge