Kategorie: HTML5

Jitsi mit einem eigenen Open Source Streaming-Server betreiben


Jitsi Videokonferenzen funktionieren bei geeigneten Einstellungen mit über 100 Teilnehmern. Voraussetzung dafür ist, dass der erste Teilnehmer (der Veranstalter) dafür sorgt, dass der erste Teilnehmer (Moderator des Raumes) in den Settings “Everyone start muted”, “Everyone start hidden” und “Everyone follows me” anwählt. Dieses Szenario ist mit über 90 Teilnehmern erfolgreich getestet worden. Dann senden die Zuschauer nicht, können ihre Kamera und Mikrofon aber selber einschalten. Wenn das der Reihe nach getan wird, kann sehr einfach ermittelt werden, wie viele gleichzeitige Teilnehmer funktionieren, da der Teilnehmer mit der geringsten Bandbreite das Nadelöhr darstellt. Für reine Vorlesungsszenarien reicht das aber häufig schon aus.

Jitsi bietet aber auch die Möglichkeit externe Streaming Dienste anzubinden wie z.B, youtube oder einen eigenen nginx-Streamingserver. Wie das technisch realisiert werden kann, wird hier kurz beschrieben. Mir fehlt leider die Zeit das detailliert zu tun, da ich nicht mehr lange für die Uni Duisburg-Essen (UDE) arbeiten werde.

Die Komponente in Jitsi, die Aufzeichnungen und Stream ermöglicht heißt Jibri. https://github.com/jitsi/jibri

Bitte beachten, wenn mehrere Streams oder Aufzeichnung zur gleichen Zeit erfolgen sollen, benötigt man eine ganze Farm von Jibri-Maschinen, die mit einem unterschiedlichen „Nickname“ (siehe unten) konfiguriert werden müssen. Best Practice: Einen jibri konfigurieren und dann klonen. („Nickname“ anpassen nicht vergessen). Das schreit eigentlich nach dynamischen Instanzen, die per Docker oder ähnlich on the fly erzeugt werden können (hier nicht realisiert, nur als Idee angerissen).

Die Installation von Jibri funktioniert, anders als in der Anleitung angegeben, auch unter Ubuntu 18.4LTS (und sehr wahrscheinlich auch 20.4LTS). Wichtig ist aber, dass unbedingt Java8 konfiguriert wird:

$ sudo update-alternatives –config java

Achtung: Anders als in der Anleitung heißen die Jitsi-internen Virtual Hosts für die beiden Control-Kanäle (hier im Beispiel heißt der Jitsi-Server jitsi.zim.uni-due.de, dass muss individuell angepasst werden):

VirtualHost “auth.jitsi.zim.uni-due.de” (in /etc/prosody/conf.avail )

und

Component “internal.auth.jitsi.zim.uni-due.de” “muc”

Diese Namen müssen sich in der jibji config.json wiederspiegeln.

Unbedingt sind dann auch die Passwörter für die richtigen “virtuellen” Domänen (mit Domain meint Jitsi ein eigenes virtuelles Subdomain-Konzept, dass gar nichts mit echten Subdomains zu tun hat) zu setzen:

$ prosodyctl register jibri auth.jitsi.zim.uni-due.de *********

$ prosodyctl register recorder recorder.jitsi.zim.uni-due.de ********

(Mit den vergebenen Passwörtern im Config-File.)

Damit alle Komponenten zusammenspielen, muss auch die Jicofo-Konfiguration angepasst werden:

Man editiere dazu  /etc/jitsi/jicofo/sip-communicator.properties, um für die MUC (Multi User Conference, Jitsi basiert ja auf Jabber) die Jitsi-Stream-Brauerei (ein Bier für den Admin ;-) , also die Jibri-Worker bekannt zu  machen. Das muss mit dem Eintrag in der jibri’s config.json korrespondieren. Jicofo muss nach der Änderung neu gestartet werden.

org.jitsi.jicofo.jibri.BREWERY=JibriBrewery@internal.auth.yourdomain.com

muss bei unserem Beispiel

org.jitsi.jicofo.jibri.BREWERY=JibriBrewery@internal.auth.jitsi.zim.uni-due.de

sein!

Dann müssen noch in /usr/share/jitsi-meet/interface_config.js
die  TOOLBAR_BUTTONS für ‘livestreaming’ aktiviert werden.

Damit kann man dann z.B. schon zu youtube streamen, wenn man dort einen Streaming Account hat. Ich denke auch Wowza würde  mit dem /etc/hosts Hack gehen, ich hatte aber keine Zeit mehr das an der UDE auszuprobieren.

Damit die Jibri-Instanzen (Farm) nicht zu youtube sondern auf einen eigenen Server streamen, einfach in /etc/hosts für youtube.com die IP des Streamingservers einsetzen. D.h. die Rechner der Jibri-Farm halten den eigenen Streamingserver für youtube. Das hat den Vorteil, dass nichts im Jitsi-Quellcode geändert werden muss.

Im Beispiel an der UDE heißt der Streamingserver livestream.zim.uni-due.de .

Die  JIBRI Farm

Jeweils in /etc/jitsi/jibri/config.json die Nicknamen ändern.

“nickname”: “jibri-nickname2″

siehe: https://github.com/jitsi/jibri/issues/187 (ganz unten)

dann

$ sudo systemctl restart jibri

In den Logfiles sieht man dann, ob sich die Jibri-Instanzen ordentlich am jicofo anmelden.

Ein eigener Open-Source Streaming-Server

Der Streaming-Server, hier ganz in Open Source ist ein nginx mit selbst kompilierten Modul realisiert worden:

Prinzipiell bin ich nach dieser Anleitung vorgegangen

https://obsproject.com/forum/resources/how-to-set-up-your-own-private-rtmp-server-using-nginx.50/

Zum Bauen des nginx:

$ sudo apt-get install build-essential libpcre3 libpcre3-dev libssl-dev

$ wget http://nginx.org/download/nginx-1.15.1.tar.gz

Das RTMP-Modul:

$ wget https://github.com/sergey-dryabzhinsky/nginx-rtmp-module/archive/dev.zip

$ tar -zxvf nginx-1.15.1.tar.gz

$ unzip dev.zip

$ cd nginx-1.15.1

Build  nginx:

$ ./configure –with-http_ssl_module –add-module=../nginx-rtmp-module-dev

$ make

$ sudo make install

Als Ergänzung habe ich auch ein LDAP-Modul in den nginx einkompiliert:

hiermit:

https://github.com/kvspb/nginx-auth-ldap/blob/master/example.conf

mit

$ ./configure –with-http_ssl_module –add-module=../nginx-rtmp-module-dev  –add-module=../nginx_ldap_module/nginx-auth-ldap-master

$ make

$ sudo make install

Restart nginx:

$ sudo /usr/local/nginx/sbin/nginx -s stop

$ sudo /usr/local/nginx/sbin/nginx

Der nginx ist selbstkompiliert und lebt nach install unter /usr/local/nginx.

Gestartet wird er bei einem Reboot über einen cronjob:

@reboot root /usr/local/nginx/sbin/nginx

@reboot root /home/zim026/worker.sh 2>/dev/null (für die Playlist, siehe unten)

So wie er nun ist, kann man den Streaming-Server mit OBS-Studio oder Videolan per RTMP füttern und sich den Stream in einem vlc medial player anschauen.

Per OBS-Studio geht das so:

Ein Profil erzeugen mit:

Streaming Service: Custom
Server: rtmp://<your server ip>/live
Play Path/Stream Key: test

Und dann mit VLC (Videolan):

rtmp://<your server ip>/live/test

Das war der einfache Teil ;-).

Ich will aber mehr und den Stream im Browser per Javascript als HLS anschauen. Dazu habe ich folgendes getan:

Der Job /home/zim026/worker.sh (landet in der Crotab) erzeugt eine dynamische Übersichtsseite:

#!/bin/bash

#erst mal dauernd
while :
do
cd /tmp/hls
#alias proj=”cd /tmp/hls”

#jhome () {
#  cd /tmp/hls

#touch test.m3u8
#touch test2.m3u8
echo > /usr/local/nginx/html/playlist_cont.html
j=0
x=X
for i in *.m3u8 ; do
if [ "${i:0:1}" != "X" ]
then
echo “<a href=’https://livestream.zim.uni-due.de/stream5.html?s=$i’>Stream: [$i] <base target=”_parent”></a><br><br>” >> /usr/local/nginx/html/playlist_cont.html
fi
j=$(( $j + 1 ))
done

OUTPUT=`cat /usr/local/nginx/html/playlist_cont.html`
if echo “$OUTPUT” | grep -q “*”; then
echo “<p>Kein öffentlicher Livestream verfübar.</p>” >/usr/local/nginx/html/playlist_cont.html
j=$(( $j – 1 ))
fi

echo  “<p>”  >>/usr/local/nginx/html/playlist_cont.html
echo $j >> /usr/local/nginx/html/playlist_cont.html
echo ‘ aktive Streams.’  >> /usr/local/nginx/html/playlist_cont.html

#cat /usr/local/nginx/html/playlist_head.html /usr/local/nginx/html/playlist.txt /usr/local/nginx/html/playlist_footer.html > /usr/local/nginx/html/playlist.html

#} # fuer das cd

sleep 5
done

Optional können auch verborgene Streams erzeugt werden, denen im Namen ein “X” vorangestellt wird. Diese tauchen dann nicht auf der Playlist auf, sind aber, wie unten in der Anleitung beschreienen, aufrufbar.

Das passende stream5.html HTML dazu, dass die hls-Videos mit Hilfe des  videojs-contrib-hls.js javascript-Library abspielt:
Siehe auch (es klappt bei mir mit Version 7):
https://videojs.com/getting-started/

Da es Umbruchprobleme im Blog gibt, hier die Datei stream5.html auch zum Herunterladen.

<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>ZIM Livestream</title>

<!–

Uses the latest versions of video.js and videojs-contrib-hls.

To use specific versions, please change the URLs to the form:

<link href=”video-js.css” rel=”stylesheet”>
<script src=”video.js”></script>
<script src=”videojs-contrib-hls.js”></script>

–>

<link href=”videojs7/video-js.css” rel=”stylesheet”>
<script src=”videojs7/video.min.js”></script>

</head>
<body>
<!– onload=”myFunction()”> –>
<img src=”UDE-logo-claim.svg” height=”100″><img src=”zim.jpg” height=”100″>
<h1>Livestream – Play Button klicken fC<r Start</h1>

<video id=”myvideo1″ controls preload=”auto”
width=”640″
height=”360″
data-setup=’{}’>

<!–   <source src=”https://livestream.zim.uni-due.de/hls/novideo.m3u8″ type=”applicat
–>

</video>
<br>
<a href=”playlist.html”>zurC<ck zur Live-Stream Auswahl</a>

<script>
window.onload = myFunction();

function myFunction(){

function getUrlParam(parameter, defaultvalue){
var urlparameter = defaultvalue;
if(window.location.href.indexOf(parameter) > -1){
urlparameter = getUrlVars()[parameter];
}
return urlparameter;
}

function getUrlVars() {
var vars = {};
var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,
vars[key] = value;
});
return vars;
}

var mystream = getUrlParam(‘s’,'Empty’);
var video = document.getElementById(‘myvideo1′);
/*alert(video);*/
var source = document.createElement(‘source’);
var streambase = ‘https://livestream.zim.uni-due.de/hls/’;
var streamurl = streambase.concat(mystream);
source.setAttribute(‘src’, streamurl);
source.setAttribute(‘type’, “application/x-mpegURL”);
video.appendChild(source);
/*let insertedNode = myvideo.insertBefore(insertedNode, source);*/
/*
video.play();
*/
}
</script>

</body>
</html>

Der Datei wird der Stream-URL durch die Playlist per Parameter übergeben und es wird ein bisschen mit Javascript gezaubert. Die Geschichte mit dem Parameter und der Playlist stammt von mir. Das kann man sicher mit einem beliebigen Framework viel eleganter machen, ist wollte allerdings eine rasche Lösung, da ich erwartet hatte, dass so etwas in Corona-Zeiten an der UDE benötigt wird.
Dieses ist meine fertige nginx.conf. Wer auf LDAP verzichten will, lässt die entsprechenden Konfigurationseintrage füe LDAP und das Modul einfach weg. Das Streaming geht auch ganz ohne LDAP. Das war nur ein Feature für die Uni Duisburg-Essen, um auch hochschulöffentliche Streams zu realisieren, die erst nach Anmeldung angeschaut werden können:

Da es Umbruchprobleme im Blog gibt, hier die Datei nginx.cfg auch zum Herunterladen.

#user  nobody;
worker_processes  10;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;

events {
worker_connections  2048;
}

http {
include       mime.types;
default_type  application/octet-stream;

#log_format  main  ‘$remote_addr – $remote_user [$time_local] “$request” ‘
#                  ‘$status $body_bytes_sent “$http_referer” ‘
#                  ‘”$http_user_agent” “$http_x_forwarded_for”‘;

#access_log  logs/access.log  main;

sendfile        on;
#tcp_nopush     on;

#keepalive_timeout  0;
keepalive_timeout  65;

#gzip  on;
#LDAP
ldap_server test1 {
url ldaps://ldap2.uni-duisburg-essen.de/ou=people,dc=uni-duisburg-essen,dc=de?uid?sub?(objectClass=inetOrgPerson);
binddn “cn=*******,ou=admin,dc=uni-duisburg-essen,dc=de”;
binddn_passwd “********”;
#group_attribute uniquemember;
group_attribute_is_dn on;
require valid_user;
}
#bis hier LDAP

server {
#listen 80;
listen 443 ssl;
#ssl on;
##  livestream.zim.uni-due.de-key.pem  livestream_cert.pem root@stream:/usr/local/nginx/certs
ssl_certificate /usr/local/nginx/certs/livestream_cert.pem;
ssl_certificate_key /usr/local/nginx/certs/livestream.zim.uni-due.de-key.pem;
server_name livestream.zim.uni-due.de;
#  server_name  localhost;
#LDAP
# auth_ldap “Anmeldung mit UDE-Unikennung/Passwort”;
# auth_ldap_servers test1;
#LDAP bis hier
#charset koi8-r;

#access_log  logs/host.access.log  main;

location / {
root   html;
index  index.html index.htm;
}

#error_page  404              /404.html;

# redirect server error pages to the static page /50x.html
#
error_page   500 502 503 504  /50x.html;
location = /50x.html {
root   html;
}

# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
#    proxy_pass   http://127.0.0.1;
#}

# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
#    root           html;
#    fastcgi_pass   127.0.0.1:9000;
#    fastcgi_index  index.php;
#    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
#    include        fastcgi_params;
#}

# deny access to .htaccess files, if Apache’s document root
# concurs with nginx’s one
#
#location ~ /\.ht {
#    deny  all;
#}
# Andreas
location /hls/ {
root /tmp;
add_header Cache-Control no-cache;
}
# Andreas
location ~  /hls/U {
root /tmp;
add_header Cache-Control no-cache;
auth_ldap “Anmeldung mit UDE-Unikennung/Passwort”;
auth_ldap_servers test1;

}

}

# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
#    listen       8000;
#    listen       somename:8080;
#    server_name  somename  alias  another.alias;

#    location / {
#        root   html;
#        index  index.html index.htm;
#    }
#}

# HTTPS server
#
#server {
#    listen       443 ssl;
#    server_name  localhost;

#    ssl_certificate      cert.pem;
#    ssl_certificate_key  cert.key;

#    ssl_session_cache    shared:SSL:1m;
#    ssl_session_timeout  5m;

#    ssl_ciphers  HIGH:!aNULL:!MD5;
#    ssl_prefer_server_ciphers  on;

#    location / {
#        root   html;
#        index  index.html index.htm;
#    }
#}

}

rtmp {
server {
listen 1935;
chunk_size 4096;

application live2 {
live on;
record off;
#Andreas
meta copy;
wait_key on;
wait_video on;
idle_streams off;
hls on;
hls_path /tmp/hls;

}
}
}

Aus der Nutzeranleitung, die ich für die UDE erstellt habe:

Livestreams bzw. Webcasts
Wählen Sie zur Nutzung von Livestreams bzw. Webcasts auf dem Server
jitsi.zim.uni-due.de  (nicht auf jitsi.uni-due.de) die Funktion “start live stream” im Menue rechts unten (drei Punkte übereinander). Vergeben Sie dann im Dialog einen aussagekräftigen Namen für den Stream (ohne Leerzeichen). Der Stream wird nicht zu youtube gesendet, wie es im GUI angezeigt wird, sondern zum Server https://livestream.zim.uni-due.de . Wenn Sie ein großes “X” dem Stream-Namen voranstellen, wird dieser nicht in der Streamübersicht angezeigt. Ihre Studierenden können den Stream dann unter der URL

https://livestream.zim.uni-due.de/stream5.html?s=X<ihrstreamname>.m3u8

betrachten. Sie müssen Ihren Studierenden den URL dann per Mail oder in Moodle mitteilen. Bitte keine Leer- oder Sonderzeichen im Stream-Namen verwenden.
Wenn Sie dem Stream-Namen mit einem großen “U” beginnen, z.B. “Utest”, können nur NutzerInnnen der UDE erst nach Eingabe der Unikennung und dem Passwort den Stream ansehen.
Stoppen können Sie den Livetream ebenfalls über das Menue.
Der Livestream kann dann über die Seite livestream.zim.uni-due.de von vielen hundert Teilnehmern angeschaut werden,

Den Streamingserver livestream.zim.uni-due.de können Sie beispielsweise aber auch mit Hilfe von OBS-Studio produzierten Livestreams aus dem Uninetz auf den Port 1935 beschicken. Die beiden Optionen mit dem vorangestellten “X” bzw. “U” gelten dann ebenfalls.

Ich hoffe diese Zusammenstellung hilft dem einen oder anderen Admin weiter. Insbesondere für große Veranstaltungen kann das sehr hilfreich sein.


Wikipedia wird mit HTTPS sicherer – Reparaturarbeiten am Pediaphon


Durch eine Anfrage eines Nutzers bin ich auf Probleme mit der Textkodierung der Pediaphon-Funktion „eigene Texte sprechen“ aufmerksam geworden. Nur ist diese Funktion auch in der Lage weiche Trennstriche, wie sie beispielsweise per Cut&Paste aus Word in das Eingabefeld kommen, zu erkennen und nicht mitzusprechen. Eine Stimme hat diese weichen Trennstriche als „bedingter Trennstrich“ oder als „Verneinung“ mitgesprochen. In Word wird das Negationszeichen, also wortwörtlich die “Verneinung” als weiches Trennzeichen verwendet.

Nach der Reparatur fiel mir ein auch einmal zu testen, ob das Sprechen von Wikipedia-Artikeln noch funktioniert, nachdem die Wikipedia, wie viele andere Webseiten nach den Snowden-Enthüllungen auch, nun nur noch per HTTPS abzufragen ist. Und tatsächlich, der Redirect von HTTP auf die entprechende HTTPS-Artikelseite führt in den Pediaphon-Scripten zu einem Problem, so dass bei allen Anfragen nur noch der normalerweise am Endes des Artikels angehängte Erklärungstext gesprochen wurde. Die Ursache war schnell gefunden, die Änderung für alle Sprachen und Stimmen zu realisieren war aber etwas aufwendiger, da alle Sprachvarianten betroffen waren.

Bei den folgenden Tests ist mir sofort ein weiteres kleines Problem aufgefallen. Vor einigen Monaten hatte ich beschlossen, die Audoausgabe defaultmäßig von Flash auf HTML5 umzuschalten, da mittlerweile fast alle mir bekannten Browser den MP3-Codec im HTML5-Audio-Tag unterstützen und Flash deshalb (und wegen der ständigen Sicherheitslücken) als Webtechnik in den Mülleimer der Geschichte gehört. Übrigens unterstütze ich HTML5-Audio für das Pediaphon schon seit Firefox 3.5 ( 2010). Allerdings mussten die Nutzer diese Option bisher aktiv auswählen.

Beim Einsatz HTML5-Audio weigern sich aber Firefox und andere Browser (neuerdings?) trotz “Pragma” „no-cache“ im HTML-Header die vom Pediaphon generierten Audio-Dateien immer neu zu laden. Die Audio-Repräsentation z.B. des Artikels zu Edward Snowden heißt im Pediaphon immer edward_snowden.mp3, auch wenn zwischendurch Parameter wie Stimme und Sprechgeschwindigkeit verändert werden. Flash, Java und Windowsmedia können durch Parameter dazu gebracht werden, die Datei immer frisch nachzuladen. HTML5-Audio weigert sich aber beharrlich und spielt den Inhalt aus dem Cache ab, auch wenn manuell die Datei per Reload in einem neuen Fenster nachgeladen wurde. Abhilfe schafft ein Trick: Den Dateien ist im URL ein Parameter angehängt, der einen Zufallswert mitliefert:

 

edward_snowden.mp3?z=<zufallswert>

 

Der Browser lädt dann die richtige Datei, hält sie aber durch den geänderten URL für eine andere. So wir nun auch HTML5-Audio im Browser dazu bewogen dynamische MP3- oder Ogg-Dateien nachzuladen und nicht die Datei aus dem Cache zu verwenden. So funktioniert das Pediaphon wieder wie gewohnt.

 

The rebirth of the cool – mit webGL kehrt Virtual Reality endlich zurück ins Web


Ende des letzten Jahrtausends wurde die Virtual Reality Modeling Language als ein Austauschformat für 3D-Geometrien standardisiert (VRML97). Interessant wurde es aber erst als VRML im Web eingesetzt wurde.

Zunächst waren leistungsfähige und teure 3D-Grafik-Workstations von Silicon Graphics (SGI) nötig um 3D in Echtzeit auf einem Desktop darzustellen. Aber Ende der neunziger Jahre standen die ersten Grafikkarten mit OpenGL Beschleunigung auch für handelsübliche PCs zu Verfügung und so begann das goldenen Zeitalter der Virtuellen Realität im Netz. Um VRML im Browser darzustellen war ein Browser PlugIn erforderlich, das die Darstellung der 3D-Welten übernahm. Richtig spannend wurde VRML durch das sogenannte External Authoring Interface ( EAI), welches  Java-Applets ermöglichte die 3D-Welten zu beeinflussen also zu programmieren. Zur Erinnerung: Damals waren Java Virtual Machines in den Browsern integriert (Netscape4, IE4).

Da nun die Nutzer der Browser schon damals wenig Lust (und wenig know how) hatten Webbrowser-PlugIns zu installieren, setze ich zu dieser Zeit viel Hoffnung in den Netscape Navigator 4.06 der mit einem VRML-PlugIn (CosmoPlayer) ausgeliefert wurde. Leider beendete der von Microsoft initiierte Browser-Krieg einerseits die Integration von Java in den Browser, andererseits gab Netscape auf und stellte den Quellcode des Navigator unter Open Source. Damit war das EAI verschwunden und es gab keine standardisierten Möglichkeiten mehr im Browser VRML Welten mit externen Schnittstellen zu programmieren. Selbst webbasierte Multiuser Virtual Reality Umgebungen wie VNET und Deepmatix funktionierten nicht mehr. Das viel spätere netzbasierte Second Life lief niemals im Browser und staubte den Hype ab.

Mit WebGL und dem API x3dom sind nun wieder standardisierte (X3D, der Nachfolgestandard zu VRML97) programmierbare (diesmal Javascript) 3D-Modelle im Browser möglich. Und das Ganze funktioniert sogar ohne PlugIn in aktuellen Browsern. Der IE von Microsoft bildet wieder einmal die unrühmliche Ausnahme. Leider hält sich dieser Konzern an keinerlei Standards. Aber x3dom verwendet für nicht unterstützte Browser ein Flash swf als Renderer für X3D, allerdings werden nicht alle folgende Beispiele im IE richtig dargestellt.

Ich erwecke hier den Puma-Robotersimulator wieder zum Leben, den ich im Jahre 2000 für das RichODL-Projekt an der FernUni in Hagen realisiert habe. Mit jquery wird hier das X3D DOM manipuliert um die Roboterachsen zu bewegen:

Ein mehr immersives Beispiel ist das PRT-Roboterlabor, welches ich 2001 in VRML modelliert habe:

Und die „Galerie oben“ der FernUni, die seinerzeit (2002) mit diesen Avataren bevölkert war:

In meiner Diss. habe ich mich im Jahre 2005 ausführlich mit diesen Techniken beschäftigt.

The rebirth of the cool“ ist der Titel einer Acid-Jazz Compilation aus den Neunzigern.

In 80 Zeilen um die Welt – Moving Map mit HTML5 Geolocation für iPhone,iPad und Android ohne Google ;-)


Das HTML5 Geolocation-Feature interessiert mich schon eine ganze Weile. Im Juli 2010 habe ich in meinem Blog eine Lösung basierend auf Openstreetmap, bzw. genauer dem großartigen Openlayers-Projekt, vorgestellt. Weil diese Seite recht viel Traffic über Google erzeugt, nun auch in meinem Blog einen ausführlicheren Artikel dazu.
Ich habe das Beispiel nun um eine Detektion der Screensize und eine live-Aktualisierung erweitert, so dass nun eine rein webbasierte ‘moving map’ a la Google maps plattformübergreifend zur Verfügung steht. Richtig spannend wird diese Seite erst wenn Sie sich bewegen (z.B mit mit einem Smartphone/iPad oder Netbook), der Browser aktualisiert dann Ihre Position!

Also in etwa die Google maps Funtionalität, rein HTML5-webbasiert und ohne Google. Das stimmt leider nicht wirklich, da beispielsweise im Firefox-Browser auch wieder Google als ‘embedded location provider’ eingetragen ist. Glauben Sie nicht? Einfach einmal about:config in die Adresszeile des Browsers eingeben (das ist die Browser-Konfiguration für Erwachsene ;-) ) und nach dem Schlüssel ‘geo.wifi’ suchen. Der Browser holt die Position per JSON bei Google https://www.google.com/loc/json ab. Wie genau Ihre Position bestimmt werden kann hängt vom Location Provider bzw. von der Implementierung Ihres Browsers und der eingeschalteten Quellen für die Lokalisation (WLAN/GSM/GPS) ab. Wenn diese Quellen nicht eingeschaltet sind, z.B. bei einem PC ohne WLAN, versucht Google die Position anhand der IP-Adresse bzw. anhand von Whois Records zu erraten. Das klappt erstaunlich genau.

Das Beispiel ist hier als iframe in mein Blog eingebettet und funktioniert auf allen HTML5 fähigen Browsern auch auf Android-Smartphones (ab 2.3 Gingerbread) und dem iPhone/iPad/iPod touch:

Benutzen Sie diesen Link um die Karte direkt auf Ihrem Android bzw IOS Smartphone anzuzeigen.

Nicht erschrecken, der Browser sollte beim Laden nun artig fragen ob diese Webseite Ihre Position erfahren darf. Dabei handelt es sich um ein HTML5-Geolocation-Feature.

Hier ist der einfache Quellcode zu sehen, ein bisschen Javascript meinerseits plus OpenLayer.js:

 

<html>
  <head>
    
    <style type="text/css">
      html, body, #basicMap {
          width: javascript(screen.width);
          height: javascript(screen.height);
          margin: 10;
      }
    </style>
 <!-- javascript(screen.width); //-->
  <!-- javascript(screen.height); //-->

    <script src="OpenLayers.js"></script>

    <script>
      function init() {
        map = new OpenLayers.Map("basicMap");
        var mapnik = new OpenLayers.Layer.OSM();
        var markers = new OpenLayers.Layer.Markers( "Markers" );
        
        map.addLayer(mapnik);
        //map = new OpenLayers.Map("basicMap");
        //var mapnik = new OpenLayers.Layer.OSM();
        //map.addLayer(mapnik);
        map.setCenter(new
        OpenLayers.LonLat(3,3) // Center of the map
          .transform(
            new OpenLayers.Projection("EPSG:4326"), // transform from WGS 1984
            new OpenLayers.Projection("EPSG:900913") // to Spherical Mercator Projection
          ), 15 // Zoom level
         );
        //var markers = new OpenLayers.Layer.Markers( "Markers" );
        map.addLayer(markers);
        var posss = new OpenLayers.Marker(0,0);
        markers.addMarker(posss);                    
                        

        navigator.geolocation.watchPosition(function(position) {       
            document.getElementById('anzeige').innerHTML="Latitude: " + position.coords.latitude + "   Longitude: " +
            position.coords.longitude + "<p>";
            var lonLat = new OpenLayers.LonLat(position.coords.longitude,
                                    position.coords.latitude)
                      .transform(
                                  new OpenLayers.Projection("EPSG:4326"), //transform from WGS 1984
                                              map.getProjectionObject() //to Spherical Mercator Projection
                                            );
            
            markers.clearMarkers();                                
            markers.addMarker(new OpenLayers.Marker(lonLat));
            //posss.lonlat(lonLat);
            map.setCenter(lonLat, 14 // Zoom level
            );
           
        });
            
      
      }
    </script>
  </head>

  <body data-rsssl=1 onload="init();">
<center>
HTML5 geolocation: 
<br />
    <div id="basicMap"></div>
<br />HTML5 geolocation<br />
<br />with Openstreetmap and OpenLayers<br />

For Android Froyo,iPhone,iPAD,iPod
<br />
Your position estimated by browser geolocation API:<p>
<div id="anzeige">(will be displayed here)<p></div>
<a href="http://www.dr-bischoff.de">Andreas Bischoff</a>

<br />(view source to see how it works, or <a
href="http://blog.robotnet.de/2011/03/30/html5-geolocation-with-openstreetmap-and-openlayers-for-android-iphone-ipad-and-ipod/">read my blog</a> ;-)
</center>
  </body>
</html>


Android Gingerbread 2.3.3 auf dem 99 Euro Androiden Vodafone 845


Nachdem sich mein neues Orange San Francisco (mit 2.3.3 Gingerbread, Cyanogen Mod 7), frisch importiert aus UK, nach nur einer Woche mit einem Sturz verabschiedet hat :-( , konnte ich nun nicht widerstehen als ich gelesen habe, dass eine frühe Cyanogen Mod 7 Beta auch für das Vodafone 845 verfügbar ist. Das kam insofern überraschend, als dass es bisher kein wirklich stabiles ROM mit Froyo für das Gerät gab.

Wer mutig ist kann Gingerbread für das Vodafone 845 hier ausprobieren:

http://forum.xda-developers.com/showthread.php?t=1096075

und hier:

http://www.android-hilfe.de/vodafone-845-forum/115220-cyanogenmod-7-auf-dem-845-a.html

Noch nicht alles läuft perfekt, das größte Manko ist derzeit noch die fehlende Kalibrierung für den Touch Screen. Der verwendetet Kernel unterstützt wohl keine Touch Screen Kalibrierung.
Das Android Keyboard sollte daher durch die HTC_Ime.zip ersetzt werden, die kalibriert werden kann.
Empfehlenswert ist es auch den ADW-Launcher durch den schlankeren Zeam Launcher zu ersetzen.

Damit läuft das Telefon überraschend flüssig!

Um an die notification bar heranzukommen muss im Launcher diese als swipe down Aktion eingestellt werden. Es scheinen auch keine Applikationen zu laufen, welche die Kamera nutzen (die Kamera selber funktioniert), weder das großartige Google Goggles noch einen QR-Code Reader konnte ich erfolgreich benutzen, beides crashed die Kamera, die erst nach einem reboot wieder funktioniert. Layar, eine App welche die Kamera im Videomodus benutzt (Augmented Reality), funktioniert aber prima.

HTML5-Audio (Pediaphon Touch Interface) und Video (http://www.jplayer.org/latest/demo-01-video-supplied-m4v/) funktionieren auch endlich mit gingerbread.

cyanogenmod7 auf dem vodafone 845

gingerbread auf dem vodafone 845

gingerbread auf dem vodafone 845

UPDATE:
Es gibt dort mittlerweile Android 2.3.5 – Cyanogen Mod 7.1.0 – Huawei U8120 – RC1 – update 11 – damit funktioniert auch die Kallibrierung des Tochscreens ganz wunderbar. Auch das Update 11 läuft mit dem Zeam-Launcher super flott. Nur das Kamera Problem besteht noch. Ansonsten besser als alle Custom ROMs (und auch besser als das Original ROM) die ich kenne, und nun schon IMHO alltagstauglich.

Das Pediaphon mit neuem Touch-Interface für Android, iPhone, iPad und iPad


Weil die HTML5-Audiounterstützung nun auf Android 2.3 Gingerbread ebenso gut funktioniert wie unter iOS auf den Apple-Mobilgeräten, war ich neugierig ob sich die gemeinsame Basis der beiden Welten (der Android-Webbrowser basiert ebenso wie der Safari-Browser auf der freien Webkit Rendering Engine) für eine HTML-basierte, an die Touch-Bedienung angepasste, eigene Oberfläche eignet. Die Ansicht, die Entwicklung von plattformübergreifenden HTML-basieren Anwendungen gegenüber nativen APPs zu favorisieren, vertrete ich schon seit langem. Besonders für e- und m-learning Anwendungen ist eine Standardisierung nützlich um zu verhindern, dass im Hochschulbereich immer knappe Entwicklungskapazitäten an einzelne Endgeräte verschwendet werden. Wiederverwendbarkeit und langer Lebenszyklus sind bei Web-basierten Anwendungen eher sicherzustellen als bei nativen APPs.

Ich wollte ursprünglich Sencha Touch einsetzen  bin aber durch einen Kollegen auf iWebkit aufmerksam geworden. iWebkit besticht durch seine Einfachheit in der Anwendung, schon rudimentäre HTML-Kenntnisse reichen aus um eine iWebkit-Seite zu erstellen. Auf dem iPhone und iPad sehen iWebkit-Seiten aus wie eine native APP und sie laufen auch ganz fabelhaft  auf Android- Nokia S60- Palm Pre- und Openmocko, basierten Geräten.

Als beispielhafte Anwendung wird hier ein eigenes Pediaphon-User-Interface für Webkit-basierte Mobilbrowser vorgestellt. Die Audioausgabe wird hier mit HTML5 realisiert, für Android 2.2 Froyo basierte Telefone gibt es auch eine Flash Alternative.

Hier einige Screenshots vom GUI (Auf einem Android 2.3 Gingerbread Emulator, aber auch schon live mit einem Orange San Francisco getestet):

Screenshot 1 Pediaphon iWebkit auf AndroidScreenshot 2 Pediaphon iWebkit auf Android

Screenshot 3 Pediaphon iWebkit auf AndroidScreenshot 4 Pediaphon iWebkit auf Android

Ausprobiert werden kann das Pediaphon iWebkit-Interface hier in Deutsch und in Englisch, Spanisch, Französisch und Italienisch.

Dienste für Smartphones an der Universität, die Campus-App für iPhone und Android


Viele Nutzer und Nutzerinnen sind heute auf dem Campus mobil unterwegs. Der Preisverfall bei UMTS-Datenflatrates (5-10 € monatlich) und Smartphones (Android-Smartphones unter 100 €) ermöglichen es, dass viele Studierende das mobile Internet nutzen. Über die mobile Nutzung des bestehenden Webangebots der Hochschule hinaus lassen sich so ganz neue Szenarien realisieren. Viele Geräte verfügen über Kameras, GPS-Empfänger und einen Kompass/Neigungssensor und Beschleunigungssensoren.

Hier wird ein Augmented Reality-basiertes Campusinformationssystem für mobile Geräte vorgeschlagen, das plattformunabhängig eingesetzt werden kann. Es handelt sich hierbei nicht um eine native App für das iPhone oder Android sondern um eine Ebene, ein ‘Layer’, für die Applikation Layar, welche für IOS, Android und Symbian erhältlich ist. Layar verfügt über eine API welche die Anbindung externer Webservices ermöglicht, die über JSON mit der Layar Applikation kommunizieren.

Karte Essenzim_essen

Die Layar-App verfügt über drei verschiedene Ansichten ortsbezogener Informationen. Die erste Ansicht ist eine Listenansicht, die zweite eine 2D-Karte und die dritte eine Überlagerung des aktuellen Kamerabildes mit passend zum Ort und der Orientierung der Kamera eingeblendeten Ortsinformationen.

zim_essenzim_essen

Eine eigene UniDUE-’Layer’ bildet Gebäudeinformationen angereichert mit Links an, ist öffentlich zugänglich und kann gemeinsam mit der Layer-App eine Augmented Reality Umgebung für den Campus realisieren.

Diese Prototyp-Layer kann folgendermaßen ausprobiert werden:

Android:

Neu: Es gibt nur eine kleine Starter-App (ein “Launcher”) die die Installation von Layer und die passenden Einstellungen automatisch vornimmt:

https://play.google.com/store/apps/details?id=de.unidue.zim.campuslauncher

Alternativ kann im Market auf dem Smartphone nach “Layar” gesucht werden (kostenlos). (bzw. im Web-Market:  https://market.android.com/details?id=com.layar)

iPhone:
Die kostenlose Layar-App: Augmented Reality für das iPhone:
https://itunes.apple.com/us/app/layar-reality-browser/id334404207

Nokia OVI Symbian (ungetestet):
https://www.layar.com/download/symbian/

Alle Plattformen:

  • In Layar “Ebene suchen” auswählen
  • nach “unid” suchen
  • Ebene Uni Duisburg-Essen starten

Es handelt sich um einen Prototypen, der derzeit nur einen kleinen Teil der Gebäude abdeckt. Der unterlagerte Webservice lässt sich zukünftig auch für alternative webbasierte-Client-Apps, beispielsweise basierend auf Sencha Touch oder iwebkit, wiederverwenden.

Audio-Wiedergabe ohne Plugin mit HTML5 und neue Positionsbestimmung mit Location-API für HTML5


Ein neues Feature für das Pediaphon ist die Plugin-lose Audiowiedergabe mit HTML5. Moderne Browser (Firefox > 3.5, Chrome, Safari) unterstützen die HTML5-Spezifikation und ermöglichen konform dem Standard die Plugin-lose Audiowiedergabe direkt im Browser. Unterstützt wird das OGG-Audioformat für das jetzt auch im neuen Design eine Metadatei generiert wird. Einfach auf der Pediaphon-Seite HTML5 bei ‘Sofort im Browser abspielen mit’ auswählen.

Auch für location based services gibt es eine Neuerung in HTML5. Das Objekt getLocation wird nun in Javascript ähnlich wie in Google-Gears
direkt von allen konformen Browsern unterstützt. Der getestete Browser Firefox 3.6 fragt dazu den geolocation-Dienst von Google im JSON Format ab. Allerdings werden momentan nur IP-Adressen und empfangene WLAN MAC-Adressen ausgewertet. Der Nutzer wird immer vom geolocation-API gefragt ob er für die Seite seine Position preisgeben möchte. Google speichert (bzw. Firefox übergibt keinen Referer) angeblich nicht von welcher Seite die Anfrage stammt. Allerdings kann Google sehr gut seine Datenbanken mit den MAC-Adressen pflegen, die die Nutzer beisteuern.
Mit ‘about:config’ in der Adressleiste kann man (nach der neuen popup-Warnung ;-) den Schlüssel ‘geo.wifi.uri’ finden, der auf
https://www.google.com/loc/json verweist.

Hier kann das Ganze ausprobiert werden. (Allerdings hat der Geonames.org Webservice wohl heute ein
Problem
).

Auch die Linux-Version von Firefox 3.6 soll auch lokale und entfernte GPS-Empfänger unterstützen, wahrscheinlich ganz einfach über diesen Schlüssel, wo doch der GPSd-NG jetzt auch JSON unterstützt. (Da gibt es wohl noch ein kleines Problem).