web-dev-qa-db-fra.com

La résolution CamcorderProfile.QUALITY_HIGH produit une vidéo verte scintillante

Je n'ai pas trouvé d'explication à cela jusqu'à présent. Fondamentalement, j'ai une classe d'enregistrement vidéo qui fonctionne à merveille lorsque setVideoSize () est réglé sur 720 x 480 sur mon Samsung Galaxy S2.

Je veux qu'il enregistre dans la résolution la plus élevée possible, donc en utilisant CamcorderProfile.QUALITY_HIGH je peux obtenir les différentes propriétés d'enregistrement de la plus haute qualité et les définir dans ma classe. Cela fonctionne pour le format de fichier, la fréquence d'images vidéo, les encodeurs et le débit binaire, mais lorsque j'essaie de régler la taille de la vidéo sur la largeur et la hauteur renvoyées par le CamcorderProfile (1920 x 1080), la vidéo enregistrée n'est qu'un scintillement vert.

J'ai remarqué que si je changeais 720 x 480 en 720 x 481, cela faisait la même chose. Par conséquent, je ne peux supposer que cela se produit lorsque la résolution n'est pas prise en charge par le téléphone. Cependant, le caméscope fourni avec le téléphone peut enregistrer en 1920 x 1080 et produit un excellent enregistrement.

Je ne peux que supposer qu'avec une résolution aussi élevée, je dois définir d'autres paramètres différemment, mais je ne peux tout simplement pas comprendre ce qu'ils pourraient être.

Quelqu'un d'autre a-t-il eu ce problème?

Merci d'avance pour toute réponse.

33
William Stewart

Je suis tombé sur cette question en essayant de résoudre le même problème.

Une solution est donnée sur xda developer http://forum.xda-developers.com/showthread.php?t=1104970&page=8 . Il semble que vous deviez définir un paramètre obscur "cam_mode" pour que l'enregistrement haute définition fonctionne:

camera = Camera.open();
Camera.Parameters param = camera.getParameters();
param.set( "cam_mode", 1 );     
camera.setParameters( param );

Dans mediarecorder, vous pouvez ensuite utiliser

mediarecorder.setVideoSize(1920, 1080);

bien que cela fonctionnera également maintenant:

mediarecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));

(Ce dernier semble avoir un débit vidéo de 20 Mo/s, vous voudrez peut-être le réduire un peu!) J'ai trouvé que je n'avais pas besoin de définir la taille de l'aperçu sur 1920x1080.

(modifier) ​​Vous devez également définir

parame.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);

ou

param.setFocusMode(Camera.Parameters.FOCUS_MODE_INFINITY);

sinon vous obtenez un délai de quelques secondes avant le démarrage de la caméra!

Quant à savoir pourquoi Samsung a implémenté l'appareil photo de cette manière, je n'en ai aucune idée. Ce n'est certainement pas convivial pour les développeurs!

19
SGS2camera

Voici comment j'ai réussi à faire fonctionner cela sur Samsung Galaxy S2. Le point critique ici est de définir la même résolution à la fois dans les paramètres de la caméra et dans la taille de la vidéo de l'enregistreur. De plus, le piratage de 'cam_mode' déjà mentionné est requis. Ainsi, j'ai permis à un utilisateur de choisir parmi trois modes de qualité: faible (800x480), moyen (1280x720) et élevé (1920x1080):

enum InternalCameraQuality {
    LOW, MEDIUM, HIGH
}

et lors de la création/du remplissage de la caméra et de l'enregistreur, j'ai fait

// signature types are irrelevant here
File start(DeviceHandler handler, FileHelper fh) throws IOException {
    file = fh.createTempFile(".mp4");

    camera = Camera.open();
    setCameraParameters(camera);
    camera.setPreviewDisplay(getHolder());
    camera.unlock();

    recorder = new MediaRecorder();
    recorder.setCamera(camera);
    setRecorderParameters(recorder);

    recorder.prepare();
    recorder.start();

    return file;
}

void setCameraParameters(Camera camera) {
    Camera.Parameters param = camera.getParameters();

    // getParams() simply returns some field holding configuration parameters
    // only the 'quality' parameter is relevant here
    if (getParams().quality != InternalCameraQuality.LOW) {
        // Samsung Galaxy hack for HD video
        param.set("cam_mode", 1);
    }

    Pair<Integer, Integer> resolution = getResolution(getParams().quality);
    param.setPreviewSize(resolution.first, resolution.second);
    param.setFocusMode(Camera.Parameters.FOCUS_MODE_INFINITY);

    camera.setParameters(param);
}

void setRecorderParameters(MediaRecorder recorder) {
    recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

    Pair<Integer, Integer> resolution = getResolution(getParams().quality);

    CamcorderProfile profile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
    profile.videoFrameWidth = resolution.first;
    profile.videoFrameHeight = resolution.second;
    recorder.setProfile(profile);

    recorder.setOutputFile(file.getAbsolutePath());
    recorder.setPreviewDisplay(getHolder().getSurface());
}

Pair<Integer, Integer> getResolution(InternalCameraQuality quality) {
    final int width, height;
    switch (quality) {
        case LOW:
            width = 800;
            height = 480;
            break;
        case MEDIUM:
            width = 1280;
            height = 720;
            break;
        case HIGH:
            width = 1920;
            height = 1080;
            break;
        default:
            throw new IllegalArgumentException("Unknown quality: " + quality.name());
    }
    return Pair.create(width, height);
}

Notez que vous devez utiliser le hack 'cam_mode' uniquement pour une qualité moyenne et élevée, sinon un scintillement vert apparaîtra en mode de qualité basse. Vous pouvez également personnaliser certains autres paramètres de profil si vous en avez besoin.

J'espère que cela a aidé.

8
Tvaroh
        List<Size> ls = parameters.getSupportedPreviewSizes();
        Size size = ls.get(1);
        sizes 1 ----------960 720
        sizes 2 ----------800 480
        sizes 3 ----------720 480
        sizes 5 -----------640 384
        sizes 6 ----------576 432
        sizes 7 ----------480 320

voici la liste des tailles et plus dans Android.

1
user1628121

Ok, j'ai testé de nombreuses variantes et la seule version qui fonctionne bien sur de vrais appareils est:

CamcorderProfile camcorderProfile    = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);

// THREE_GPP works well but only on Phones            
//  camcorderProfile.fileFormat = MediaRecorder.OutputFormat.THREE_GPP;

// so better you use MPEG_4 for most Devices and PC
camcorderProfile.fileFormat = MediaRecorder.OutputFormat.MPEG_4;
camcorderProfile.videoCodec = MediaRecorder.VideoEncoder.MPEG_4_SP;

mrec.setProfile(camcorderProfile);
1
Ingo

J'ai connu des problèmes similaires comme celui-ci dans le passé. Ce que vous faites semble bien, mais voici quelques suggestions qui pourraient vous aider à déboguer le problème:

Assurez-vous de sélectionner une résolution prise en charge

int cameraId = 0; // using back facing camera
Camera camera = Camera.open(cameraId);
Camera.Parameters cameraParams = camera.getParameters();
List<Camera.Size> supportedPreviewSizes = cameraParams.getSupportedPreviewSizez();

// find suitable Camera preview size from list and set your CamcorderProfile to use that new size

Une fois que vous avez trouvé une taille d'aperçu appropriée, assurez-vous de réinitialiser votre SurfaceView - vous devrez le redimensionner pour s'adapter au changement de rapport hauteur/largeur

L'API MediaRecorder utilise SurfaceView, donc si votre vue de surface n'est pas configurée correctement, cela entraînera le scintillement vert que vous voyez

Assurez-vous que vous utilisez un débit binaire vidéo qui peut prendre en charge la nouvelle résolution - essayez d'augmenter le débit binaire vidéo pour doubler ce qu'il était initialement défini (* notez que cela affecte considérablement la taille de votre fichier de sortie)

CamcorderProfile.QUALITY_HIGH renvoie la résolution de caméra prise en charge la plus élevée possible. Assurez-vous d'utiliser le bon identifiant de caméra (avant ou arrière) - peut-être que la caméra arrière prend en charge 1080p, mais pas la caméra frontale?

J'espère que les conseils vous aideront!

0
jagsaund