web-dev-qa-db-fra.com

Comment capturer l'écran le plus rapidement possible avec adb?

Récemment, j'ai écrit un client PC qui peut afficher et contrôler l'écran de mon téléphone Android en temps réel à l'aide de adb . J'utilise le singe pour contrôler l'appareil et cela fonctionne bien. Le problème est de savoir comment saisir l'écran du téléphone et l'afficher en douceur.

La première solution que j'ai proposée consiste à saisir continuellement les variables framebuffer à adb (comme la fonction de capture d'écran de DDMS). Maintenant, quand je le fais, la performance est tout à fait inacceptable. Le taux de trame capturé à partir de framebuffer est aussi bas que 5 par seconde (la taille de trame est 800 * 480). Mon programme ressemble à son hoquet lorsque je glisse sur le téléphone.

Mon programme est écrit en Java en utilisant ddmslib pour saisir framebuffer.

ajouter:
J'ai trouvé qu'il était très lent d'encoder les données brutes framebuffer au format .png, sinon ce serait un moyen rapide de transmettre une image brute compressée.

Comment puis-je améliorer la vitesse de capture de l'écran à un niveau régulier?

25
Robot Dreamer
adb Shell screencap -p | Perl -pe 's/\x0D\x0A/\x0A/g' > screen.png

La source:

http://blog.shvetsov.com/2013/02/grab-Android-screenshot-to-computer-via.html

23
steveha

Vous pouvez utiliser:

$ adb Shell screencap -p> sc.png

qui ne fonctionne malheureusement pas (le fichier est corrompu), vous avez donc le choix

$ adb Shell screencap -p /mnt/sdcard/sc.png
$ adb pull /mnt/sdcard/sc.png

bien que cela soit relativement rapide, ce n'est probablement pas aussi rapide que vous le souhaitez.

9
Diego Torres Milano

si la partie lente est une conversion brute en png (time adb Shell screencap -p /sdcard/x.png est considérablement plus lente que time adb Shell screencap /sdcard/nonpng.raw, comme je l'ai dans les jeux) et que png n'est pas nécessaire, vous pouvez le faire comme ici https://github.com/sowcow/shot . Il convertit les données brutes au format ppm simple et convertit les ppm en bmp en utilisant imagemagick avec à peu près aucune surcharge après avoir obtenu les données brutes.

upd:

Ce script shell de max_plenert est un meilleur exemple:

adb Shell screencap /sdcard/mytmp/rock.raw
adb pull /sdcard/mytmp/rock.raw
adb Shell rm /sdcard/mytmp/rock.raw

// remove the header
tail -c +13 rock.raw > rock.rgba

// extract width height and pixelformat:
hexdump -e '/4 "%d"' -s 0 -n 4 rock.raw
hexdump -e '/4 "%d"' -s 4 -n 4 rock.raw
hexdump -e '/4 "%d"' -s 8 -n 4 rock.raw

convert -size 480x800 -depth 8 rock.rgba rock.png
8
Pyro

Dans .bash_profile sur mon mac:

function droidShot() {
  /full_path_to_droid_sdk/platform-tools/adb Shell screencap -p | Perl -pe 's/\x0D\x0A/\x0A/g' > $1.png
}

usage:

droidshot whatever

et le fichier apparaît dans quelqu’un.png

4
William Jockusch

En utilisant cette méthode, mon application continue de fonctionner à son débit maximal.

adb pull /dev/graphics/fb0

Cela extraira les données brutes du tampon d'images. Il semble avoir la même largeur que l'écran, mais la hauteur est complétée. Le tampon de trame sur mon périphérique semble être au format RGBA8888. Pour obtenir exactement ce qui est affiché à l'écran, vous devez ignorer le canal alpha.

Notez que cela prend ~ 0,8 seconde à télécharger pour moi (résolution: 480x854) mais si je le télécharge sur une boucle continue, cela n’affecte pas la cadence de l’appareil.

3
Grant Peters

C’est une solution lente, je suis sûr que c’est le moyen le plus rapide que vous pouvez trouver dans les solutions adb,

# this line require a superuser privilege:
adb Shell "su -c 'cat /dev/graphics/fb0 > /sdcard/capture.raw'"

adb pull /sdcard/capture.raw

ffmpeg -loglevel panic -f rawvideo -pix_fmt bgr32 -s 320x480 -i \ 
    capture.raw -vcodec png -vframes 1 capture.png; 

 this is the same code into my web application

2
christian

De docs :

Prendre une capture d'écran de l'appareil

La commande screencap est un utilitaire Shell permettant de prendre une capture d'écran de l'affichage d'un périphérique. Dans un shell, la syntaxe est la suivante:

screencap <filename>

Pour utiliser la capture d'écran à partir de la ligne de commande, tapez ce qui suit:

$ adb Shell screencap /sdcard/screen.png

Voici un exemple de session de capture d'écran utilisant le shell adb pour capturer la capture d'écran et la commande pull permettant de télécharger le fichier à partir du périphérique:

$ adb Shell
shell@ $ screencap /sdcard/screen.png
Shell@ $ exit
$ adb pull /sdcard/screen.png

Enregistrement d'un écran de périphérique

La commande screenrecord est un utilitaire Shell permettant d’enregistrer l’affichage des périphériques exécutant Android 4.4 (API niveau 19) ou supérieur. L'utilitaire enregistre l'activité de l'écran dans un fichier MPEG-4.

Note: Audio is not recorded with the video file.

Un développeur peut utiliser ce fichier pour créer des vidéos promotionnelles ou de formation. Dans un shell, la syntaxe est la suivante:

screenrecord [options] <filename>

Pour utiliser screenrecord à partir de la ligne de commande, tapez ce qui suit:

$ adb Shell screenrecord /sdcard/demo.mp4

Arrêtez l'enregistrement d'écran en appuyant sur Ctrl-C, sinon l'enregistrement s'arrête automatiquement au bout de trois minutes ou à la limite de temps définie par - time-limit.

Pour commencer à enregistrer l'écran de votre appareil, exécutez la commande screenrecord pour enregistrer la vidéo. Ensuite, exécutez la commande pull pour télécharger la vidéo du périphérique sur l'ordinateur hôte. Voici un exemple de session d'enregistrement:

$ adb Shell
shell@ $ screenrecord --verbose /sdcard/demo.mp4
(press Ctrl-C to stop)
Shell@ $ exit
$ adb pull /sdcard/demo.mp4

L’utilitaire screenrecord peut enregistrer à la résolution et au débit binaires demandés, tout en conservant le rapport hauteur/largeur de l’affichage du périphérique. L'utilitaire enregistre à la résolution d'affichage et à l'orientation natives par défaut, avec une durée maximale de trois minutes.

Il y a certaines limitations connues de l'utilitaire screenrecord dont vous devez être conscient lors de son utilisation:

Certains appareils peuvent ne pas être en mesure d'enregistrer avec leur résolution d'affichage native. Si vous rencontrez des problèmes avec l'enregistrement d'écran, essayez d'utiliser une résolution d'écran inférieure . La rotation de l'écran pendant l'enregistrement n'est pas prise en charge. Si l'écran pivote pendant l'enregistrement, une partie de l'écran est coupée dans l'enregistrement.

1
Sergey Shustikov

Il y a un programme screenrecord depuis Android 4.4.

adb Shell screenrecord /data/local/tmp/test-video.m4v
adb pull /data/local/tmp/test-video.m4v ~/test-video.m4v
0
Joseph Lennox

Certaines personnes ont dit à Perl qu’il y avait plusieurs façons de faire une chose. :-) Quoi qu'il en soit, celui-ci fonctionnera peut-être mieux (puisqu'il n'y a pas d'expression régulière) et pourrait résoudre le problème dans Cygwin sous MS Windows (dont Perl définit \n en tant que CRLF):

adb Shell screencap -p | Perl -pe 'BEGIN { $/="\cM\cJ"; $\="\cJ"; } chomp;' > screen-$(date +%Y%m%d_%H%M%S).png
0

J'ai amélioré la solution de @ steveha:

Créez un script Shell avec: ' Android-screenshot ' avec le contenu suivant:

adb Shell screencap -p | Perl -pe 's/\x0D\x0A/\x0A/g' > screen-`date +%Y-%m-%d_%X`.png

Placez ce fichier dans votre répertoire bin local ou dans tout autre fichier $ PATH de votre choix.

Cela vous permettrait de sauvegarder les fichiers avec un horodatage dans le répertoire actuel.

N'oubliez pas de rendre le script Shell exécutable à l'aide de

chmod +x Android-screenshot
0
Ram Vijapurapu