Friday, January 18, 2013

This blog is obsolete

I moved my blogs on wordpress. They are now here:

ildiariodimarco.wordpress.com (personale notes on various topics, in Italian)

macintoshnotes.wordpress.com (technical notes, mostly related to the Mac world, in English)

wii4dida.wordpress.com (blog of the project "Wii4Dida, 2010-2011, in Italian)

lenotedijulia.wordpress.com (simple content on school topics, in Italian)

Wednesday, July 2, 2008

ED-MEDIA 2008 act II

Vienna, July 2.

Dimitris Alimisis presented the TERECoP Project - an EU project on using LEGO Mindstorms as a teaching tool. They are developing a series of modules for teachers, so that they learn how to use robots to teach students various things (like e.g. principles of programming). A web site of their is
eclass.gunet.gr. Among the project's partners also some Italians: the Museo civico di Rovereto and University of Padova.

I could not choose many other talks to listen because I had 2 presentations:
  • Requirements for videolectures: which system is the best for you?
  • A Web 2.0 Enabled Digital Library

Tuesday, July 1, 2008

ED-MEDIA 2008

Some notes from EDMEDIA

Here we are, in Vienna.
Today one interesting talk:
Stéphane Jacquemart of the Palette project presented some ingredients useful for Personal Learning Environments. Among them:
Open Identificaton:
Quotability, reusability of content:
Presence information
  • XMPP (jabber)
He also quoted dataportability.org

Wednesday, May 28, 2008

Converting ppt to pdf (and many others) from Java

JODConverter is a nice project that deploys OpenOffice to obtain services. It allows converting files from Office to OpenOffice, to pdf, to flash etc.
It can be embedded in a Webservice, in a Website, or driven from a Java program. The JODConverter site offers the possibility to perform online conversion.

Since NeoOffice is a branch of OpenOffice, it works also with it.

Here is a simple example (taken from the JODConverter website and completed by adding the right imports etc. - sorry the indentation is killed from Blogger's editor).

To use it (on a Mac) you need:
- to install NeoOffice
- to download the JODConverter jars
- to start NeoOffice as a service (in a shell, execute:
/Applications/NeoOffice.app/Contents/MacOS/soffice.bin -headless -accept="socket,port=8100;urp;")
- compile and run the following java program (make sure that you include the jars in the library!)

package jod;
import java.io.File;
import com.artofsolving.jodconverter.openoffice.connection.OpenOfficeConnection;
import com.artofsolving.jodconverter.openoffice.connection.SocketOpenOfficeConnection;
import com.artofsolving.jodconverter.DocumentConverter;
import com.artofsolving.jodconverter.openoffice.converter.OpenOfficeDocumentConverter;
import java.net.ConnectException;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Main {
public static void main(String[] args) {
new Main();
}
Main(){
//put here the name of your source file
File inputFile = new File("/Users/ronchet/Desktop/3.5.ppt");
//put here the name of your destination file
File outputFile = new File("/Users/ronchet/Desktop/3.5.pdf");
//Note that for determining which conversion must be applied, JODConverter will use the files'extensions

// connect to an OpenOffice.org instance running on port 8100
OpenOfficeConnection connection = new SocketOpenOfficeConnection(8100);
try {
connection.connect();
} catch (ConnectException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
// convert
DocumentConverter converter = new OpenOfficeDocumentConverter(connection);
converter.convert(inputFile, outputFile);
// close the connection
connection.disconnect();
}
}

Just a note: an alternative way to convert slides is to use (within ppt) a VBA script to export the slides into a bunch of jpgs. Here is a such script, and here another version of the same.
Also, for exporting all text, here is another VBA script.

Tuesday, May 27, 2008

Office on Mac - without M$

OpenOffice has been for long time a free alternative to MS Office.
On the Mac it needs to install X11 - which can be a bit annoying. There is though an interesting alternative: NeoOffice. It is an OpenOffice independent branch dedicated to the Mac and based on Aqua. It also opens the new MS formats (e.g. ppx) - OpenOffice does not yet! It also has an interface to Databases (can access a database through JDBC).

NoMu is a nice add on that installs a menu in the finder for launching NeoOffice in a different mode (e.g. as presentation or spreadsheet tool).

Alternatively, you can launch it from the shell as
/Applications/NeoOffice.app/Contents/MacOS/soffice.bin file.doc
/Applications/NeoOffice.app/Contents/MacOS/soffice.bin -impress file.ppt
/Applications/NeoOffice.app/Contents/MacOS/soffice.bin -calc file.xls

NeoOffice is scriptable (in several languages: Basic, Java, Javascript, Python). I found it difficult to find documentation - it took me a lot of frustrating googling hours - until I realized that OpenOffice and StarOffice documentation apply also to NeoOffice - maybe with some differences.
Here are some resources:

Thursday, May 22, 2008

Bugged setting Dialog in quicktime java!

I've been fighting this bug for days... When calling SGSettingsDialog() from java (the dialog that allows you to choose source, codec etc) I got a strange behavior. The dialog does not accept mouse-downs on the video codec selection popup menu, and the appearence of the dialog looks here and there a bit corrupted. But I did remember that at one time I had been able to select a MP4 codec, so it had to be possible...
I googled for days, without much luck. Yes, qtjava is great but its documentation is soooo poor...
Finally today I accidentally stumbled in the solution:
"We've had sporadic reports from customers of corrupted settings dialogs since QT 7 -- deleting the QuickTime preferences seems to clear it."
Yes, yes, yes: it works! Deleting the preferences (/Users/yourname/Library/Preferences/Quicktime Preferences) fixes it!

Friday, May 16, 2008

Building with qtjava a video recorder that allows previewing while recording

QuickTime for Java is a set of cross-platform APIs which allows Java developers to build multimedia, including streaming audio and video, into applications and applets.
That's quite nice, and to learn using it there is a book written by Chris Adamson and published by O'Reilly, available also in electronic form though O'reilly commons. The book goes through a series of examples. A basic example in chapter 6 shows how to record a video on disk. There is a problem though: while the machine records, the video stream is NOT shown on the PC screen. Obviously one would like instead to get a preview of what is being recorded while recording (so that e.g. you know how to move the camera).
It looks like a very basic requirement, so I started hunting for solutions on the net. Several hours of googling with various keywords produced more or less an empty set...

The best I could find was some sort of hint on an O'Reilly's Mac Dev Center - but still it was a bit vague - I wanted a fully developed example. At the bottom of the page I noticed an unanswered question by Amit Zohar: "So how do I capture video and audio in Java and save it into a movie file while allowing for a preview as well?" - Yes, this is what I also wanted to know.
The question was more that two years old... I decided to write to Amit to see if in the meantime he had been able to solve the problem - and yes he did! He was so kind to send me his OpenGL based code. THANKS AMIT!

Unfortunately over the last two years OpenGL has undergone some radical transformation - repackaging the classes, changing some methods' signatures etc. - so I had to update the code a bit - but it wasn't too much work. So in case someone has the same problem, here I publish here the solution. To run the code (on a Mac) you need to make sure that:
  • you installed QuickTime - this will also install the qtjava library as QTjava.zip in /System/Library/Java/Extensions;
  • you download the current release build of the Java OpenGL library - you must unzip the downloaded file;
  • your compile-time libraries must include QTJava.zip, the two jars of jogl: jogl.jar and gluegen-rt.jar
  • you put the directory containing the jnilib files that were downloaded with jogl in the runtime library path (e.g. by specifying the switch -Djava.library.path=/path/of/your/jnilib/files in your java command)
I think you need QuickTime Pro to be able to record - QuickTimeViewer is not enough - but I'm not 100% sure.

In principle it should work also on Windows - but I did not check.

The program "MiniRecorder" will first show you a window where you can play with various params (you can leave them as they are or change some of the options - e.g. change the default compressor to MPEG-4 and adapt its video quality to the level you like) - when you click ok you'll have an empty window with some buttons.
Video recording will begin when you click on "start" - you'll have a preview of what is being recorded. Click on "stop" to interrupt capturing, then "preview" to review the captured video, and "accept" or "discard" to keep/delete the file containing the saved video. Closing the window to quit.

The video is saved in a file named as you specify in the code. In the code you can also choose the directory where it will be located.

The code is composed by two classes: QTSessionFactory for initialization (adapted from Adamson's book) and MiniRecorded (essentially the code that Amit sent me with some modifications).

Here is the code:

//------ Class QTSessionFactory
package QT;
import quicktime.*;
public class QTSessionFactory {
private Thread shutdownHook;
private static QTSessionFactory instance;
private QTSessionFactory( ) throws QTException {
super( );
// init
QTSession.open( );
// create shutdown handler
shutdownHook = new Thread( ) {
public void run( ) {
QTSession.close( );
}
};
Runtime.getRuntime( ).addShutdownHook(shutdownHook);
}
private static QTSessionFactory getInstance( ) throws QTException {
if (instance == null)
instance = new QTSessionFactory( );
return instance;
}

public static void setupQTSsession( ) throws QTException {
// gets instance. if a new one needs to be created,
// it calls QTSession.open( ) and creates a shutdown hook
// to call QTSession.close( )
getInstance( );
}
}

//---- Class MiniRecorder

package QT;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
/* ----------------- */
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/* ----------------- */
import java.nio.IntBuffer;
/* ----------------- */
import com.sun.opengl.util.Animator;
/* ----------------- */
import javax.media.opengl.GL;
import javax.media.opengl.GLCanvas;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLAutoDrawable;
/* ----------------- */
import quicktime.QTException;
import quicktime.QTNullPointerException;
import quicktime.QTSession;
import quicktime.app.view.MoviePlayer;
import quicktime.app.view.QTFactory;
import quicktime.app.view.QTJComponent;
import quicktime.io.OpenMovieFile;
import quicktime.io.QTFile;
import quicktime.qd.QDGraphics;
import quicktime.qd.QDRect;
import quicktime.std.StdQTConstants;
import quicktime.std.StdQTException;
import quicktime.std.movies.Movie;
import quicktime.std.sg.SGSoundChannel;
import quicktime.std.sg.SGVideoChannel;
import quicktime.std.sg.SequenceGrabber;
import quicktime.util.QTBuild;

public class MiniRecorder implements StdQTConstants {
// The directory where files are saved
String activeDirectory = "/Users/ronchet/tmp/";
String fileName="movie";
// quicktime
SequenceGrabber sg;
QDGraphics gWorld;
QTFile qtFile;
Movie movie;
MoviePlayer moviePlayer;
JComponent qtc;
GLCanvas canvas;
int taskingDelay = 20;
int maxFrameRate = 30; // increasing may degrade preview speed
int compressorType = StdQTConstants.kComponentVideoCodecType;
int IMAGEWIDTH=640;
int IMAGEHEIGHT=480;
// camera flags
boolean cameraReady = false;
boolean isRecording = false;
boolean isPreviewing = true;
// image buffers
//MR int pixelData, newPixelData;
IntBuffer pixelData, newPixelData;
int WIDTH, HEIGHT;
// stats
int paintCount = 0;
long startMilli, endMilli;
// ui
JFrame frame;
Component imagePanel;
JPanel centerPanel, emptyPanel,buttonsPanel;
JButton startButton, stopButton, previewButton, acceptButton, discardButton;
final String START_RECORDING = "Start";
final String STOP_RECORDING = "Stop";
final String PREVIEW_RECORDING = "Preview Recorded Video";
final String ACCEPT_RECORDING = "Accept Recorded Video";
final String DISCARD_RECORDING = "Discard Recorded Video";
final String TITLE = "miniRecorder";
final Color BACKGROUND = Color.WHITE;
/**
* constructor.
*/
public MiniRecorder() {
try {
QTSessionFactory.setupQTSsession();
getQTinfo();
initSequenceGrabber();
} catch (Exception ex) {
log("Unable to initialize camera");
QTSession.close();
}
initUI();
}

private void getQTinfo() {
log("java.library.path: " + System.getProperty("java.library.path"));
log ("VERSIONS:");
log("OpenGL : " + javax.media.opengl.glu.GLU.versionString);
log("QT : " + QTSession.getMajorVersion( ) + "." + QTSession.getMinorVersion( ));
log("QTJ : " +QTBuild.getVersion( )+"." +QTBuild.getSubVersion( ));
}

private void initSequenceGrabber() throws Exception {
sg = new SequenceGrabber();
SGVideoChannel vc = new SGVideoChannel(sg);
// init pixelData
QDRect cameraImageSize = new QDRect(IMAGEWIDTH ,IMAGEHEIGHT);
gWorld = new QDGraphics(cameraImageSize);
WIDTH = gWorld.getPixMap().getPixelData().getRowBytes() / 4;
HEIGHT = cameraImageSize.getHeight();
pixelData=IntBuffer.allocate(WIDTH * HEIGHT);
newPixelData=IntBuffer.allocate(WIDTH * HEIGHT);

sg.setGWorld(gWorld, null);

vc.setBounds(cameraImageSize);
vc.setUsage(quicktime.std.StdQTConstants.seqGrabRecord
| quicktime.std.StdQTConstants.seqGrabPlayDuringRecord);
vc.setFrameRate(maxFrameRate);
vc.setCompressorType(compressorType);
vc.settingsDialog( );
SGSoundChannel sc = new SGSoundChannel (sg);
sc.setUsage(StdQTConstants.seqGrabRecord);

// init bufferedImage
int intsPerRow = gWorld.getPixMap().getPixelData().getRowBytes() / 4;
pixelData = IntBuffer.allocate(intsPerRow * cameraImageSize.getHeight());

cameraReady = true;
}

private void initUI() {

frame = new JFrame(TITLE);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBackground(BACKGROUND);

// buttons panel
buttonsPanel = new JPanel();
buttonsPanel.setBackground(BACKGROUND);
startButton = new JButton(START_RECORDING);
buttonsPanel.add(startButton);
startButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
try {
startRecording();
} catch (Exception e) {
e.printStackTrace();
}
}
});

stopButton = new JButton(STOP_RECORDING);
stopButton.setEnabled(false);
buttonsPanel.add(stopButton);
stopButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
stopRecording();
}
});


previewButton = new JButton(PREVIEW_RECORDING);
previewButton.setEnabled(false);
buttonsPanel.add(previewButton);
previewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
previewRecording();
}
});


acceptButton = new JButton(ACCEPT_RECORDING);
acceptButton.setEnabled(false);
buttonsPanel.add(acceptButton);
acceptButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
acceptRecording();
}
});

discardButton = new JButton(DISCARD_RECORDING);
discardButton.setEnabled(false);
buttonsPanel.add(discardButton);
discardButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
discardRecording();
}
});


// bottom panel - for buttons
JLabel space = new JLabel(" ");
buttonsPanel.add(space);
frame.add(BorderLayout.SOUTH, buttonsPanel);


// image panel
centerPanel = new JPanel();
centerPanel.setBackground(BACKGROUND);

emptyPanel = new JPanel();
emptyPanel.setPreferredSize(new Dimension(IMAGEWIDTH, IMAGEHEIGHT));
emptyPanel.setBackground(Color.ORANGE);

if (cameraReady) {
imagePanel = buildOpenGLCameraView();
centerPanel.add(imagePanel);
} else {
centerPanel.add(emptyPanel);
}


frame.add(BorderLayout.CENTER, centerPanel);
Toolkit toolkit = java.awt.Toolkit.getDefaultToolkit ();
Dimension screensize = toolkit.getScreenSize ();
frame.setBounds(0, 0, screensize.width, screensize.height-250);
frame.setVisible(true);

}

private void startRecording() {
log("start recording");
isRecording = true;
startButton.setEnabled(false);
stopButton.setEnabled(true);
buttonsPanel.validate();
startMilli = System.currentTimeMillis();

try {
prepareAndStartRecord();
} catch (QTException e) {
log("Unable to start recording");
} catch (QTNullPointerException e) {
log("Unable to start recording");
}

}


public void stopRecording() {
log ("stop recording");
try {
endMilli = System.currentTimeMillis();
sg.stop();
log("recording stopped");
double seconds = (endMilli - startMilli) / 1000;
double previewFps = paintCount / seconds;
log("preview stats: seconds=" + seconds + " fps=" + previewFps);

} catch (StdQTException e) {
log("Unable to stop recording");
}
isRecording = false;
stopButton.setEnabled(false);
previewButton.setEnabled(true);
frame.validate();
}

public void previewRecording() {
log("preview recording");
previewButton.setEnabled(false);
acceptButton.setEnabled(true);
discardButton.setEnabled(true);

// replace previewPanel with movie player
qtc = getQuicktimeMovieComponent(qtFile);
qtc.setPreferredSize(new Dimension(IMAGEWIDTH ,IMAGEHEIGHT));
setCenterComponent(qtc);

// Start playing the movie
try {
movie.start();
log("movie playing");
} catch (Exception e) {
e.printStackTrace();
}
}

public void acceptRecording() {
log("accept recording " + qtFile.getName());
acceptButton.setEnabled(false);
discardButton.setEnabled(false);
startButton.setEnabled(true);
setCenterComponent(imagePanel);
try {
movie.stop();
log("movie stopped");
} catch (StdQTException e) {
e.printStackTrace();
}
}

public void discardRecording() {
log("discard recording " + qtFile.getName());
acceptButton.setEnabled(false);
discardButton.setEnabled(false);
startButton.setEnabled(true);
setCenterComponent(imagePanel);
try {
movie.stop();
log("movie stopped");
} catch (StdQTException e) {
e.printStackTrace();
}
discardQTFile();
}

private void setCenterComponent(Component component) {
centerPanel.removeAll();
centerPanel.add("Center", component);
frame.validate();
}

/**
* Initializes the SequenceGrabber. Gets it's source video bounds, creates a
* gWorld with that size. Configures the video channel for grabbing,
* previewing and playing during recording.
*/

private void prepareAndStartRecord() throws QTException {
QTFile movieFile = getQTFile();
sg.setDataOutput(movieFile,
quicktime.std.StdQTConstants.seqGrabToDisk);
sg.prepare(false, true);
sg.startRecord();

// setting up a thread, to idle the sequence grabber
Runnable idleCamera = new Runnable() {

public void run() {
try {
while (sg != null && isRecording) {
Thread.sleep(taskingDelay);
synchronized (sg) {
sg.idleMore();
sg.update(null);
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
};
(new Thread(idleCamera)).start();
}

/**
* This creates a Panel, which displays the camera image using OpenGL
*/
public Component buildOpenGLCameraView() {
GLEventListener glEventListener = new GLEventListener() {

// Called by the drawable immediately after the OpenGL context is initialized.
public void init(GLAutoDrawable drawable) {
log("init OpenGL");
GL gl = drawable.getGL();
gl.glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
gl.glShadeModel(GL.GL_FLAT);
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
}

// Called by the drawable to initiate OpenGL rendering by the client.
public void display(GLAutoDrawable drawable) {
if (!isRecording) {
return;
}
GL gl = drawable.getGL();
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1);
gWorld.getPixMap().getPixelData().copyToArray(0, pixelData.array(), 0,
WIDTH * HEIGHT);
flipVertically(pixelData);
gl.glDrawPixels(WIDTH, HEIGHT, gl.GL_BGRA,
gl.GL_UNSIGNED_INT_8_8_8_8_REV, newPixelData);
paintCount++;
}


public void flipVertically( IntBuffer pixelData ) {
for ( int row=0; row<HEIGHT; row++ ) {
System.arraycopy(pixelData.array(), row*WIDTH, newPixelData.array(), (HEIGHT-row-1)*WIDTH, WIDTH) ;
}
}
// Called by the drawable during the first repaint after the
// component has been resized.
public void reshape(GLAutoDrawable drawable, int i, int x, int width,
int height) {

GL gl = drawable.getGL();
// MR GLU glu = drawable.getGLU();
gl.glViewport(0, 0, WIDTH, HEIGHT);
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glLoadIdentity();
// MR glu.gluOrtho2D(0.0, (double) WIDTH, 0.0, (double) HEIGHT);
gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glLoadIdentity();

}

// Called by the drawable when the display mode or the display device
// associated with the GLDrawable has changed.
public void displayChanged(GLAutoDrawable drawable,
boolean modeChanged, boolean deviceChanged) {
}


};

GLCapabilities caps = new GLCapabilities();
canvas=new GLCanvas(caps);
canvas.addGLEventListener(glEventListener);
canvas.setBounds(0, 0, IMAGEWIDTH ,IMAGEHEIGHT);
Animator animator = new Animator(canvas);
animator.start();
return canvas;
}

public QTFile getQTFile() {
String path = activeDirectory + fileName;
int count = 0;
qtFile = new QTFile(path + count);
while (qtFile.exists()) {
count++;
qtFile = new QTFile(path + count);
}
log("getQTFile: " + path + count);
return qtFile;
}

public void discardQTFile() {
log("discardQTFile: " + qtFile.getName());
qtFile.deleteOnExit();
}

public void log(String text) {
System.out.println(text);
}


/**
* Gets a Movie component for the specified file
*/
protected JComponent getQuicktimeMovieComponent(QTFile qtFile) {
QTJComponent qtcmp = null;

try {
// Create the movie
movie = Movie.fromFile(OpenMovieFile.asRead(qtFile));
movie.setBounds(new QDRect(IMAGEWIDTH ,IMAGEHEIGHT));
moviePlayer = new MoviePlayer(movie);

// Create the QuickTime Movie Component
qtcmp = QTFactory.makeQTJComponent(moviePlayer);
return qtcmp.asJComponent();
} catch (QTException err) {
err.printStackTrace();
return null;
}
}


public static void main(String args[]) {
new MiniRecorder();
}
}

Wednesday, March 12, 2008

I hate itunes.

I hate itunes. Instead of developing software with the user in mind – Apple has been unbeatable on this field in the past – itunes seems to be written with a different main goal: protect intellectual property, so that it be difficult for the users to “share” the tunes bought on line. I do not have anything against this goal – but the result is that simple things (like e.g. moving pictures into the iphone, or managing synchronization among multiple machines - home, office and iphone) become more difficult than necessary. Yes, I hate itunes.

Friday, March 7, 2008

Comparing directories in MacOsX

I needed to check if a directory and its backup were equal.
I found two nice ways of doing this:
- diff -rq dir1 dir2
and the very powerful FileMerge (one of the Apple Developer Tools) thac can be lauched frm the shell with "opendiff".

Friday, February 29, 2008

iphone tools

I've just got my iphone from USA - thanks Alberto for your help!

I'll keep here a list of useful tools I found.

Essential tools
  • First of all, install Sources/Bigboss's Recommended... !
System Stuff:
  • Make sure that you have BSD Subsystem
  • OpenSSH
  • Term-vt100
  • AFPd. It allows you to mount your iphone wirelessly from the mac, and view its content as three external disks. This way you can e.g. transfer the pictures taken with the iphone - they are in Mobile's Home Dir/Media/DCIM/100APPLE - That's good for exporting pictures - but not for importing (they must be referenced in some database updated by itunes, so that's not so trivial - yet).

  • ToDoList (how can a similar tool be missing from the standard distribution ?)
  • BossPrefs allows to quickly en(dis)able Edge, Wifi, BT, SSH (note that in 1.1.3 you cannot change your pwd, so having ssh always on is a real threat!)
  • 1.1.3 Safari Patch allows viewing local files in Safari (therefore it allows e.g. viewing local pdfs)
  • SysInfo 1.0b - info about your hardware and processes
  • Fring
  • AVPlayer (requires Docs, which requires 1.1.3/4 Safari Patch)
Useful tools
  • HP-11C is a nice emulator of an HP scientific calculator - there are other flavors too!
  • Contacts|HomeScreen allows having an icon on the Springboard to access directly your contacts
  • Search allows you searching into your contacts and events
  • LocateMe uses GSM cells to find your (approximate) location
  • Converter converts among a lot of different units (including clothing)
  • RemoteNote (requires JiggyRuntime)
  • Snapture
Not essentals, but somehow nice things
  • Categories (to be installed together with Poof) allows having "folders" into the Springboard
  • Summerboard enhances a bit the Springboard look
  • Sensors gives you feedback from the accelerometer.
Most wanted:

It would be nice to have:
  • an EDGE/GRPS modem to use the iphone as a modem for accessing the web from the laptop! There are several ways to hack this through an ad-hoc network between laptop and iphone, but setting them up requires some time and my experience with them wasn't great:
    • I followed without success some instructions (here)
    • a method based on a SOCKS (see here) worked with some web sites, and not with others (why?)
    • I've found a third possibility, not tested yet.
  • the possibility of accessing a BlueTooth GPS!
  • a browser that remembers the passwords and fields (Firefox is under development)
  • the possibility to do cut and paste (apple is working on it?)
  • Flash...
  • the possibility of viewing the iphone as an external disk when connected to the laptop via USB (I've found but not yet tested a commercial solution: Megaphone )
  • the possibility of synchronizing Calendar and Contacts over the wireless without using itunes (Funambol does it only for contacts right now)
  • the possibility of loading music and photos without using itunes
WebApps

Some general info

here is a selection of info (mostly taken from "la guida completa su iphone" - in italian)
  • Info about unlocking - see iphone.unlock.no
  • Come faccio a controllare che Firmware ha il mio iPhone? Basta digitare sul tastierino numerico *3001#12345#* e premere CALL.
  • Come mai anche se ho es. 5 giga liberi sull’iPhone mi viene detto “memoria in esaurimento” oppure “spazio su disco insufficiente”? Perchè i programmi che si scaricano dall’installer vanno ad intaccare una memoria particolarmente ridotta (quella della partizione firmware di circa 23 mb) e non quella dell’iPhone.
  • Esiste un modo per aggirare questo ostacolo?Sì, bisogna 1. installare Terminal - 2. digitare mv /Applications /private/var - 3. digitare [attenzione sono “elle” e “enne” minuscole] ln -s /private/var/Applications /Applications -4. Riavviate. Così facendo le applicazioni vanno in /privata/var che non è altro che la partizione degli 8 giga. Oppure spostare la cartella Applications manualmente (via ssh) in /private/var e poi da terminale digitare ln -s /Applications /private/var/Applications. Prima di riavviare controllare via ssh che il collegamento nella root ( / ) sia presente e che il collegamento ti porti effettivamente alla vera cartella Applications.
  • Quali differenze ci sono tra Attivazione, Jailbreak e Sblocco?L’Attivazione si fa per accedere al menu principale di iPhone senza usare iTunes, per attivarlo in modo da utilizzarlo come un iPod Touch.Il Jailbreak è l’operazione che permette di scrivere il File System, dove risiede il Firmware. Necessario per consentire l’uso di applicazioni terze.Lo Sblocco è l’ultima operazione, quella che permette di accedere, con l’aiuto di applicazioni terze, alla parte telefonica di iPhone in modo che sia fruibile con qualsiasi Sim.
  • Non ho il Wi-Fi, come faccio?Puoi utilizzare il tuo Mac come access point, andando in Preferenze di Sistema >> Condivisione >> Internet e settare come “uscita” Airport. Metti una password ed è fatta! Naturalmente se hai un Mac con Airport integrata). Una descrizione completa la trovi nel blog di APNIBI
  • Posso mandare sms multipli?Non direttamente da iPhone, ma con l’ausilio sempre di WeTool o SmsD questa operazione è ora fattibile. [ WeTool si ottiene scaricando la Source http://app.weiphone.com/installer/ ]Tra parentesi WeTool può anche eliminare le chiamate singole.
  • Posso fare video con l’iPhone?No, per il semplice motivo che l’iPhone non è dotato di una video camera, ma solo di una fotocamera da 2 mpixel. Ora hanno creato un piccolo programma (Drunknbass) che registra, tramite fotocamera, video della durata di 5 secondi; esiste la possibilità di rivederli, ma non di registrarli.
  • Posso leggere/modificare documenti Word, Excel, Pdf?Li puoi leggere se allegati alle mail che ti mandano, ma non puoi modificarli. Esiste poi un programma che si chiama PdfViewer che permette di leggere i file pdf che vengono inseriti tramite SSH in un’apposita cartella interna dell’iPhone.
  • E posso scaricarli dalle mail?All’inizio no, così come per le foto, potevano essere visualizzati solamente nelle mail. Ad oggi si è aggiunto un programma che si chiama MNPLight ( http://movenplay.gforge.inria.fr/iphone ) che permette di scaricarli e visualizzarli anche off-line.
  • Posso inserire allegati nelle mie Mail in uscita?Sì se si tratta di foto che hai sincronizzato con iPhoto e se si tratta di foto scattate direttamente da iPhone. Per allegare documenti, devono essere presenti nelle cartelle interne di iPhone (cioè inseriti preventivamente tramite ssh).
  • Posso allegarne uno solo alla volta?Per quello che riguarda iPhone sì. Con SendFile (programma terzo) puoi aggiungerne anche fino a tre (testato) attraverso un abbastanza laborioso lavoro a ritroso dopo aver salvato ogni volta la Mail.
  • iPhone apre i siti Flash?No, al momento non è possibile.
  • EDGE configuration in Italy - see configurazione EDGE
  • Logging in via terminal - Using username root and password alpine does not work - here is why: When vt100 launches it runs the login command with a flag to login as root. The mobile user is not allowed to login as root. You basically have to launch vt100 with root permissions. Big Boss has a package that fixes this. Install SUID Lib Fix under 1.1.3 tweaks. That sets the suid bit on login which will fix the problem. Now you will be able to use the root password to login when terminal prompts you. You might also want to install the BSD Subsystem 2.0 Term fix under Tweaks. This fixes the problem where backspace submits a space instead.

Thursday, January 31, 2008

Downloading videos from Youtube

(and saving them on your HD). There are web sites providing such service. See e.g.

http://get2pc.com/post.php

http://keepvid.com/

On the iphone this can be done with MyMedia (to get it, add to the iphone installer the source http://studio-psk.com/app).

Monday, January 21, 2008

Extracting an audio track from a video on a Mac

I was looking for a free software for extracting an audio track from a movie.

I found one that does much more: it's called MPEG Streamclip, and it is produced by an italian company called Squared5.

It is a powerful video converter, player, editor for Mac and Windows. It can play many movie files, not only MPEGs; it can convert MPEG files between muxed/demuxed formats for authoring; it can encode movies to many formats, including iPod; it can cut, trim and join movies.

MPEG Streamclip can also download videos from YouTube and Google by entering the page URL.

Wednesday, December 19, 2007

Chronicle of buying an Apple iphone from chronochrono.

Last update of this report: Feb. 1, 2008.

This is the story of my attempt of buying an iphone from a small Boulder based company called chronochono (www.chronochrono.com). It might be of interest for other people considering to to the same.

Chronochrono sells iphones with several options (locked, unlocked, activated with a stealthsim).

On Dec 13 I bought an iphone with a stealthsim from them. On their web site they wrote they would be shipping within the day, but my unfortunate experience is that after several days they kept saying that they were waiting for the stealthsim to arrive (therefore at least their statement about immediate availability is not true!).

On Dec 19 I had a mail exchange with Chris Wentz (probably the only person behind this company) and he tried to reassure me. We agreed that he would have shipped the iphone immediately, and the stealth sim when available. On Dec 20 I did get a message form USPS - but it was only to say that Chris had requested a shipping - I never got the confirmation from USPS that they actually got the shipment.

On Dec.23 still the USPS site did not give any sign of having received the shipment (you can still see here the current status...). It might be that USPS is sloppy in updating its site, but that's a bit hard to believe... Chris sent me an email: "I don't know what else I can do to convince you it was sent. I will try to have usps cancel the shipment. If you get the phone please send it back to me. I gave you a refund through Google Checkout so you would not be worried, and I don't want to risk any legal hassles.".

On the evening of the same day Chris sent me another mind-boggling message: "Marco, I wanted to make sure you have your USPS #- ec 930 079 600 US. It should update with new information once your package is in Greece at customs. One of my assistants put in the wrong number when entering it into Google. I guarantee it will be there By new years, and if not I will refund you $40 for the delay. I appreciate your business and if there is anything I can do to make it better please let me know."
Now - if he actually sent me a refund - and requested to cancel the previous shipment as he said in the morning - why was he shipping once more? (btw, I'm not living in Greece...)

I had another element of suspicion: on their home page they have a PayPal logo. However when you buy from them , you do not really have the option to go through PayPal, but can only go through the Google Checkout option (which does not really fully protect you from fraud like Paypal does). Unfortunately I did notice that only after buying, when I became suspicious... I also told Chris that if that's the case he should remove the Paypal logo - but he never did. (Note: after the whole story ended I've got an explanation for this - see the Addendum below).

January 6, status update, end of the story. After coming back from a short ski vacation (Jan 2-6, in Stubai Tal, Austria), I had the news from our offices that Chronochrono fully refunded us on Dec. 24. That's good. About the shipments of Dec 19 and Dec 23, there are no other traces on USPS, you can check on your own by using the link above and the code.

What did I learn?

All is well that ends well. Well, sort of. I did not get the iphone but
at least I've got the money back.
It looks like some people have been luckier:
I found a forum where a French guy says he bought an iphone from them. On the other hand, if you take a look at the comments to this posting, and you'll find that other people went through the same troubles I had (they did not get the iphone - but in the end both of them had their money back as I did).

Well, I might have been paranoid. But to me, the bottom line is that if you write "we ship the same day" you have to do it. Or at least, you should immediately take the initiative and explain to your customer why you did not. Especially if you run a small, little know business without an established reputation.

February 1, 2008 - Addendum

I've got an e-mail from Chris:
At your suggestion I have done two things- I have added a current stock status to the top of most products. Also, I have added a business line for customers to call and ask questions or leave messages.
I looked into having the paypal logo removed, but since the webstore is made with a template, it is there permanently. Paypal pays my hosting company to put it on all the webstores. Because of this I am unable to edit the logo from the site. I would also ask you to remember my communication with you and prompt refund when I realized I could not deliver the product well.

Good to see that things can somehow improve. The text on the chronochrono's website is also clearer now about the fact that the you can only pay via Google Checkout (or bank transfer for larger orders).






Wednesday, December 5, 2007

Trieste, Workshop on Rich-Media Technologies for Science Dissemination

Ismael Peña-López presented hiw view of how to use Web 2.0 tools: http://ictlogy.net/
I learned about Scott Wilson and his Personal Learning Environment.

Saturday, October 20, 2007

ffmpeg on Mac OsX

ffmpegX is a nice solution - but if you need to use ffmpeg from a script or from the shell, then yo must install ffmpeg and probably also lame. See Stephen Jungles blog.

Friday, October 12, 2007

e-learning conferences - calls for papers

IADIS INTERNATIONAL CONFERENCE MOBILE LEARNING 2008

Algarve, Portugal, 11 to 13 April 2008

http://www.mlearning-conf.org/

Deadline for submissions: 16 November 2007


EISTA 2008
http://www.socioinfocyber.org/eista2008.
June 29th to July 2nd, 2008
Orlando, Florida,USA
Submissions: November 14th, 2007

INTED2008
International Technology, Education and Development Conference
http://www.iated.org/inted2008
3 to 5 March 2008
Valencia, Spain
The deadline for abstracts/proposals is 15 November 2007.

WEBIST 2008
International Conference on Web Information Systems and Technologies
http://www.webist.org
Full paper submission: November 2, 2007
Funchal, Madeira, 4 - 7 May, 2008
(has a track on e-learning)

Friday, October 5, 2007

TechCrunch40: Lots of new ideas...

Benjamin Dandoy pointed me to techcrunch40 : it's a mine of new ideas! A series of really innovative services.

Friday, September 28, 2007

ICL conference in Villach - part 2: Talks

The talks were organized in parallel sessions - although the organizers did their best to make sure that all the papers were presented there was a non negligible number of no-show, which messed up the program by changing the timing mand making it difficult to jump from one session to the other. So I surely missed many good talks - parallel sessions are always a problem. Of those I attended to, some did not give me much, others were interesting. Here is a short note of those that I found worth listening.

- Claudia Steinberger from Klagenfurt gave a nice talk on her experience in running a course using web 1.5 (i.e. some web 2.0 techniques without a complete and satisfactory integration). I heard her talking about mobile learning a few years ago, I always like her talk. Simple stuff but well grounded, without nonsense.

- Matjaz Debeve, a slovenian PhD student, presented yet another system for recording videolectures. he mentioned a number of commercial system, I have to look at them in detail:
The main point of his work was to have a cart with all the necessary mounted on it (Camera, pc, microphones) and to provide subtitles and gesture language for deaf people.
He mentioned that they plan to conduct a usability evaluation using SUMI questionnaires and semistructured interviews (see also the FAO site on this).
They also plan to be compliant with the EBU reccomendations, event though they are for TV.

- Frantisek Schauer and Miroslava Ozvoldova presented a system for accessing and steering physics experiments on line. Experiments are built with the ISES system. Cute, but I'm not so convinced of their advantage with respect to real experiments or simulations.

Someone (maybe Balacheff?) mentioned applications of neuroscience to learning - Natural learning by Zulls - also quoted here: it looks like a theory that describes learning as a process that (to me) sonds very similar to the scientific method. Also Kolb's learning styles is something I should look a bit into (see also this).

BTW, following some pointers on Web 2.0 I found a site that looks juicy: social computing magazine.

The whole special track on Schools and ICT was good. Here are the talks:

Erika Hummer presented a report on supporting the introduction of ICT (and in particolar LMS) in Austrian classes (elsa.schule.at). One of the points in the project was to allocate money to teachers for doing extra work in the form of pairing to coach and mentor a colleague (ecoaching.schule.at). Another point was trying to relief the problema connected with the management of HW and SW by hosting Moodle instances in a centralized location (www.edumoodle.at).

Anton Knierzinger and Marianne Ebenhofer presented their initial work on intercultural integration in the primary schools. It seems that ICT can be really effective on this crucial issue.

Then came my talk on Interactive Whiteboards. The slides are available on Slideshare: Introducing interactive whiteboards in the schools: an experience report (paper written together with Benjamin Dandoy).
Unlukily my talk was at the same time as the one by Enrique Canessa and Marco Zennaro, that presented their fully automated lecture recording EyA system that I saw last week in Trieste, but we had the time to talk and exchange ideas couple of times in these days.

Stevens Scott (Carnegie Mellon University) presented a work aimed at helping novice Physics teachers.: the PATHWAY project. It is based upon the informedia project that extracts metadata from movies by creating transcripts and analysing them. They also have a question-answering system that analyses the query and provids a pre-digested response in the form of a movie (www.infsearch.cs.cmu.edu/idvl.htm)

Thursday, September 27, 2007

ICL conference in Villach

Villach, Kaernten, Austria. ICL conference (Interactive Computer-aided Learning).

Running a conference (or better, many) can be a business. There are associations that charge you a lot for participating and then they give you minimal support. I remember going to a IASTED conference, and for 600 Euro we almost did not even have coffee during coffee breaks. They had promised printed proceedings - but then they discovered that shipping them to a Greek island (the conference was in Rhodes) coasted too much - so we never got them. The conference was good - in the end a conference is as good as its participants make it - but I felt ripped off. (BTW, there were also "special" hotel prices that were higher than I could find - in the very same hotel - in a travel agency...).

This conference is not of that sort. The organizers made a remarkable job in finding sponsors and covering some lunches and dinners, even at a lower-than-average participation fee. I do have some experience in organizing events, and I know how that can be difficult.

I wish they did the same good job in the selection of the keynote speakers. Well, on paper they made reasonable choices, but in practice the start wasn't that good, and the end was even worse..
The first three keynote speeches were... well, depressing. I’ll omit their names here.

The first stated that XML allows to address the issue of having semantic indexing of the content, and to make the content machines understandable. Well, maybe if you add a couple of other layers on top of XML it might be true… Embarrassing, maybe he should go back and take a look at the layers of the Semantic Web. He also said that with mathML you can do calculations - e.g. take derivatives of a function. I believe it's only a markup language, not an engine...

Another keynote gave a talk about the evolution of e-learning, from web pages to Learning Management System (LMS), to Managed Learning Environments (MLE), to Personal Learning Environments (PLE) to a future Collaboration Environments. These last should be based on the emergine of web applications (like the google office suite). Well, the whole issue was very much technology-oriented and rather blurred . He did not comment on the how and why this technology should deliver more efficient collaboration models, and spent his time demonstrating that you can edit a document, or even open a browser, in a browser's window. Well, fun and exciting, we know that network computing will probably be the next big thing, and that Bill has nightmares about that, but terribly out of focus.

The third keynote was supposed give a talk on how Web 2.0 will enhance e-learning.
The first statement was a sign of the confusion that is often present when people speak about Web 2.0. When comparing the two approaches, he mentioned that “Web 1.0 is static while Web 2.0 is dynamic”. Ouch, CGI? He continued saying that “Web 1.0 is based on client-server paradigm, and Web 2.0 is based on Web Services”. Irritating, why do people talk about things they do not know? And this nonsense was more or less all he had to say about Web 2.0. The rest of the talk was a quick run through what they do in their labs, including an applet-based (web 2.0?) collaborative environment and a virtual reality system (in a joke (?) defined as Web 3.0).

Luckily then the series of weak keynote speaches was interrupted. Nicholas Balacheff gave a good talk. among his points was that learning is a change of behavior, but real learning is in the rationale of the change of behavior. Among the things he has worked on there is Aplusix , an Algebra Learning Assistant.

The fifth keynote, Di Paolo from Stanford, gave a very good talk about the transformations that a University has to go through to support LongLifeLearning. His slides are available at scpd.stanford.edu. The parameters that are important according to him are:
  • provide a quick response
  • students expect to work in a workgroup
  • availability 24/7/365
  • learning by searching
  • from connectivity to collectivity
  • provide customized learning
  • be aware that there is a strong interest in international interactions
  • provide challenges
  • give the prossibiliy to preview courses and read students evaluation before registering
  • view students as customers: eliminate delays and inefficiencies
  • be ready to deliver technology smarter,smaller, faster, anywhere
  • always give up-to-date information (time stamp every token of information you provide)
Next a movie about shifthappens (shifthappens.wikispaces.com) was given. It was of the "Information Anxiety" series :-) but it was certainly interesting.

On the following day, the next keynote was for me the worst surprise (but wait, read also the long discussion in the comments to this posting!).
Taisir Subhi Yamin’s talk (Ulm University, Germany) was pushing the idea that e-learning’s mission is to help the “talented and gifted students”. There is even a pedagogical method and a system that has been put in place to pursue this idea: the Renzulli Learning. Sounds odd to me… My experience is that (at least at the University level) there is not much you can do to help very good students: they find their own way. Sure, advising helps, but I do not believe e-learning can effectively do that. And after all it’s only 10% of the students, and it is a joy to wok with them…
Also with very bad students (e.g. students with serious problems in their background knowledge) there is little hope to have an impact. Where the teacher (or e-learning) can really make a difference is in between: with the large mass of average students.
Ok, things may be a little different in primary and secondary school, BUT Yamin pushed his argument to say that “gifted students should be grouped in special classes”. I VIOLENTLY OBJECT TO THIS VIEW! The next step would be to create special classes for students with problems, and it took us the last 50 years to understand this is WRONG. The road outlined by Yamin is more than wrong: it’s frightening, and to me it even evokes bad memories from the fist half of the last century…

The last keynote (Ulf Daniel Ehlers, Vice President of the European Foundation for Quality Elearning) was -of course- on quality in e-learning. Good part of Ehlers' talk was on serendipity, continuous innovation, perpetual beta. Most of the content of the talk can be found in form of a summary here. It wasn't the kind of talk that changes your life but it was a honest and reasonable talk. Among the things I found interesting was the notion of transition from Transmissive Learning (distribution of learning material) to Expansive Learning (collaboration and reflection). Kind of obvious but nicely wrapped!
On the same line, he was quoting Schulmeister 2005 - but I was not able to find document he was referring to, not even through Schulmeister's home page. During my search through Schulmeister's publications however I found an interesting classification of Interactivity in Multimedia (in German!).
Later on I discovered that Ulf Daniel Ehlers maintains a blog on quality in e-learning.