web-dev-qa-db-fra.com

Comment enregistrer un écran et prendre des captures d'écran en utilisant Android API?

Contexte

Android a une nouvelle API sur KitKat et Lollipop, pour capturer l’écran en vidéo. Vous pouvez le faire soit via l'outil ADB, soit via un code (à partir de Lollipop).

Depuis la sortie de la nouvelle API, de nombreuses applications utilisant cette fonctionnalité sont apparues, permettant ainsi d’enregistrer l’écran. Microsoft a même créé sa propre application concurrente Google Now-On-Tap.

En utilisant ADB, vous pouvez utiliser:

adb Shell screenrecord /sdcard/video.mp4 

Vous pouvez même le faire depuis Android Studio lui-même.

Le problème

Je ne trouve aucun tutoriel ni explication sur la procédure à suivre à l'aide de l'API, ce qui signifie dans le code.

Ce que j'ai trouvé

Le seul endroit où j'ai trouvé ce sont les documentations ( ( ici , sous "Capture et partage d'écran"), me disant cela :

Android 5.0 vous permet d'ajouter des fonctionnalités de capture et de partage d'écran à votre application avec les nouvelles API Android.media.projection. Cette fonctionnalité est utile, par exemple, si vous souhaitez activer le partage d'écran dans une application de visioconférence.

La nouvelle méthode createVirtualDisplay() permet à votre application de capturer le contenu de l'écran principal (affichage par défaut) dans un objet Surface, que votre application peut ensuite envoyer sur le réseau. L'API permet uniquement la capture de contenu d'écran non sécurisé, et non de l'audio du système. Pour commencer la capture d'écran, votre application doit d'abord demander l'autorisation de l'utilisateur en ouvrant une boîte de dialogue pour la capture d'écran à l'aide d'une intention obtenue via la méthode createScreenCaptureIntent().

Pour obtenir un exemple d'utilisation des nouvelles API, voir la classe MediaProjectionDemo dans le projet exemple.

Le problème est que je ne trouve aucun échantillon "MediaProjectionDemo". Au lieu de cela, j'ai trouvé un exemple de "Capture d'écran", mais je ne comprends pas comment cela fonctionne. Lorsque je l'ai exécuté, tout ce que j'ai vu est un écran clignotant et je ne pense pas que cela enregistre la vidéo. un fichier. L'échantillon semble très buggy.

Questions

Comment puis-je effectuer ces actions en utilisant la nouvelle API:

  1. commencer l'enregistrement, y compris éventuellement l'audio (micro/haut-parleur/les deux).
  2. arrête d'enregistrer
  3. prendre une capture d'écran au lieu d'une vidéo.

Aussi, comment puis-je le personnaliser (résolution, fps demandés, couleurs, durée ...)?

37
android developer

La première étape et celle que Ken White a suggéré à juste titre et que vous avez peut-être déjà couverte est le exemple de code fourni officiellement.

J'ai utilisé leur API plus tôt. Je suis d'accord que la capture d'écran est assez simple. Mais, l'enregistrement d'écran est également sous des lignes similaires.

Je répondrai à vos questions en 3 sections et le terminerai par un lien. :)


1. Lancer l'enregistrement vidéo

private void startScreenRecord(final Intent intent) {
 if (DEBUG) Log.v(TAG, "startScreenRecord:sMuxer=" + sMuxer);
 synchronized(sSync) {
  if (sMuxer == null) {
   final int resultCode = intent.getIntExtra(EXTRA_RESULT_CODE, 0);
   // get MediaProjection 
   final MediaProjection projection = mMediaProjectionManager.getMediaProjection(resultCode, intent);
   if (projection != null) {
    final DisplayMetrics metrics = getResources().getDisplayMetrics();
    final int density = metrics.densityDpi;

    if (DEBUG) Log.v(TAG, "startRecording:");
    try {
     sMuxer = new MediaMuxerWrapper(".mp4"); // if you record audio only, ".m4a" is also OK. 
     if (true) {
      // for screen capturing 
      new MediaScreenEncoder(sMuxer, mMediaEncoderListener,
       projection, metrics.widthPixels, metrics.heightPixels, density);
     }
     if (true) {
      // for audio capturing 
      new MediaAudioEncoder(sMuxer, mMediaEncoderListener);
     }
     sMuxer.prepare();
     sMuxer.startRecording();
    } catch (final IOException e) {
     Log.e(TAG, "startScreenRecord:", e);
    }
   }
  }
 }
}

2. Arrêter l'enregistrement vidéo

 private void stopScreenRecord() {
  if (DEBUG) Log.v(TAG, "stopScreenRecord:sMuxer=" + sMuxer);
  synchronized(sSync) {
   if (sMuxer != null) {
    sMuxer.stopRecording();
    sMuxer = null;
    // you should not wait here 
   }
  }
 }

2.5. Pause et reprise de l'enregistrement vidéo

 private void pauseScreenRecord() {
  synchronized(sSync) {
   if (sMuxer != null) {
    sMuxer.pauseRecording();
   }
  }
 }

 private void resumeScreenRecord() {
  synchronized(sSync) {
   if (sMuxer != null) {
    sMuxer.resumeRecording();
   }
  }
 }

J'espère que le code aide. Voici le lien original vers le code auquel j'ai fait référence et à partir duquel cette implémentation (enregistrement vidéo) est également dérivée. .


3. Prendre une capture d'écran au lieu de la vidéo

Je pense que par défaut, il est facile de capturer l'image au format bitmap. Vous pouvez toujours continuer avec MediaProjectionDemo exemple pour capturer une capture d'écran.

[EDIT]: chiffrer le code pour la capture d'écran

a. Pour créer un affichage virtuel en fonction de la largeur/hauteur du périphérique

mImageReader = ImageReader.newInstance(mWidth, mHeight, PixelFormat.RGBA_8888, 2);
mVirtualDisplay = sMediaProjection.createVirtualDisplay(SCREENCAP_NAME, mWidth, mHeight, mDensity, VIRTUAL_DISPLAY_FLAGS, mImageReader.getSurface(), null, mHandler);
mImageReader.setOnImageAvailableListener(new ImageAvailableListener(), mHandler);

b. Puis lancez la capture d’écran en fonction d’une intention ou d’une action -

startActivityForResult(mProjectionManager.createScreenCaptureIntent(), REQUEST_CODE);

Arrêtez la projection média-

sMediaProjection.stop();

c. Puis convertir en image -

//Process the media capture
image = mImageReader.acquireLatestImage();
Image.Plane[] planes = image.getPlanes();
ByteBuffer buffer = planes[0].getBuffer();
int pixelStride = planes[0].getPixelStride();
int rowStride = planes[0].getRowStride();
int rowPadding = rowStride - pixelStride * mWidth;
//Create bitmap
bitmap = Bitmap.createBitmap(mWidth + rowPadding / pixelStride, mHeight, Bitmap.Config.ARGB_8888);
bitmap.copyPixelsFromBuffer(buffer);
//Write Bitmap to file in some path on the phone
fos = new FileOutputStream(STORE_DIRECTORY + "/myscreen_" + IMAGES_PRODUCED + ".png");
bitmap.compress(CompressFormat.PNG, 100, fos);
fos.close();

Plusieurs implémentations (code complet) de l'API Media Projection sont disponibles. Quelques autres liens qui peuvent vous aider dans votre développement-

  1. Enregistrement vidéo avec MediaProjectionManager - site Web

  2. Android-ScreenCapture - github selon Android du développeur :)

  3. screenrecorder - github

  4. Capturer et enregistrer Android Écran utilisant les API MediaProjection - site Web


J'espère que ça aide :) Bon codage et enregistrement d'écran!

PS: Pouvez-vous s'il vous plaît me dire l'application Microsoft dont vous parlez? Je ne l'ai pas utilisé. Voudrais essayer:)

61
bozzmob