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?
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
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.
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.
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
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
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.
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;
De docs :
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
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.
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
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
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