Android: la diffusion de la caméra comme mjpeg

Après plusieurs jours de recherche, DONC google et je commence à m'abandonner, j'ai donc pensé que je pourrais aussi bien de poster ici.

Je crée une application android qui devrait offrir une sorte de chat vidéo. Comme ce doit être aussi proche que possible de en temps réel, j'ai lu sur différents protocoles et a décidé d'essayer MJPEG pour les débutants (ne concernant pas avec de l'audio pour l'instant).

Dès maintenant en streaming les données sont me rend fou. La connexion sera établie, l'application commence à écrire l'appareil photo les images de prévisualisation de la rivière, mais ni VLC ni mplayer démarrer la lecture de la vidéo. La surveillance de la connexion révèle que les données arrivent.

Connexion
Ce code est exécuté par un async task, un auditeur est notifié à succès:

try
    {
        ServerSocket server = new ServerSocket(8080);

        socket = server.accept();

        server.close();

        Log.i(TAG, "New connection to :" + socket.getInetAddress());

        stream = new DataOutputStream(socket.getOutputStream());
        prepared = true;
    }
    catch (IOException e)
    {
        Log.e(TAG, e.getMessage();
    }

Sur mon PC, j'execute 'mplayer http://tabletIP:8080" et la tablette enregistre une connexion (et commence donc mon streamer et l'aperçu de la caméra). Cela fonctionne aussi avec VLC.

Streaming Ceci écrit l'en-tête du flux:

if (stream != null)
{
    try
    {
        //send the header
        stream.write(("HTTP/1.0 200 OK\r\n" +
                      "Server: iRecon\r\n" +
                      "Connection: close\r\n" +
                      "Max-Age: 0\r\n" +
                      "Expires: 0\r\n" +
                      "Cache-Control: no-cache, private\r\n" + 
                      "Pragma: no-cache\r\n" + 
                      "Content-Type: multipart/x-mixed-replace; " +
                      "boundary=--" + boundary +
                      "\r\n\r\n").getBytes());

        stream.flush();

        streaming = true;
    }
    catch (IOException e)
    {
        notifyOnEncoderError(this, "Error while writing header: " + e.getMessage());
        stop();
    }
}

Après la diffusion est déclenchée par la Caméra.onPreviewFrame() Rappel:

@Override
public void onPreviewFrame(byte[] data, Camera camera)
{
    frame = data;

    if (streaming)
        mHandler.post(this);
}

@Override
public void run()
{
    //TODO: cache not filling?
    try
    {
                    //buffer is a ByteArrayOutputStream
        buffer.reset();

        switch (imageFormat)
        {
            case ImageFormat.JPEG:
                //nothing to do, leave it that way
                buffer.write(frame);
                break;

            case ImageFormat.NV16:
            case ImageFormat.NV21:
            case ImageFormat.YUY2:
            case ImageFormat.YV12:
                new YuvImage(frame, imageFormat, w, h, null).compressToJpeg(area, 100, buffer);
                break;

            default:
                throw new IOException("Error while encoding: unsupported image format");
        }

        buffer.flush();

        //write the content header
        stream.write(("--" + boundary + "\r\n" + 
                      "Content-type: image/jpg\r\n" + 
                      "Content-Length: " + buffer.size() + 
                      "\r\n\r\n").getBytes());

        //Should omit the array copy
        buffer.writeTo(stream);

        stream.write("\r\n\r\n".getBytes());
        stream.flush();
    }
    catch (IOException e)
    {
        stop();
        notifyOnEncoderError(this, e.getMessage());
    }
}

Il n'y a aucune exception n'est levée. Le mHandler s'exécute dans son propre HandlerThread. Juste pour être sûr, j'ai essayé d'utiliser un AsyncTask, en vain (btw, est-ce mieux?).

De l'encodage des cadres sont beaux sur l'android côté, je enregistrés dans des fichiers jpg et pourrait ouvrir de leur.

Ma conjecture est que j'ai à regrouper les données d'une manière ou d'avoir à définir des options pour la prise ou quelque chose, mais....eh bien, je suis coincé.

tl;dr: VLC ne pas jouer stream, mplayer dit "cache pas remplir", le problème est probablement dans le dernier segment de code, besoin d'aide~ 🙂

Merci de bien vouloir!

OriginalL'auteur Managarm | 2013-02-11