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.