From mboxrd@z Thu Jan 1 00:00:00 1970 From: =?utf-8?Q?Ludovic_Court=C3=A8s?= Subject: Making a QEMU animation Date: Wed, 15 Apr 2020 23:06:38 +0200 Message-ID: <87y2qwlaqp.fsf@inria.fr> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Return-path: Received: from eggs.gnu.org ([2001:470:142:3::10]:41584) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jOpF3-0007DM-Nk for guix-devel@gnu.org; Wed, 15 Apr 2020 17:06:42 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]:47497) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1jOpF3-0000WW-Iv for guix-devel@gnu.org; Wed, 15 Apr 2020 17:06:41 -0400 Received: from [2a01:e0a:1d:7270:af76:b9b:ca24:c465] (port=38936 helo=ribbon) by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1jOpF1-0000qq-Qw for guix-devel@gnu.org; Wed, 15 Apr 2020 17:06:40 -0400 List-Id: "Development of GNU Guix and the GNU System distribution." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-devel-bounces+gcggd-guix-devel=m.gmane-mx.org@gnu.org Sender: "Guix-devel" To: guix-devel --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Hi! Here=E2=80=99s the script I used to make a QEMU animation of the installati= on process: it grabs screenshots at regular intervals through QEMU. You can then assemble them to form an animated GIF with: convert -loop 0 -delay 20 /tmp/qemu-movie-0*ppm /tmp/install.gif The GIF can be compressed with: mogrify -layers optimize-frame /tmp/install.gif On IRC, Ricardo came up with this command to produce the video at (with a fade-in, proper frame rate, etc.): ffmpeg -framerate 30 -pattern_type glob -i \ 'qemu-guix-install.selected/qemu-movie-*.ppm' -c:v libvpx-vp9 -v= sync \ cfr -crf 31 -pix_fmt yuv420p -b:v 0 -filter_complex \ "setpts=3D5*PTS,loop=3Dloop=3D60:size=3D1:start=3D0,fade=3Dt=3Di= n:st=3D0:n=3D60" \ out3.webm Ludo=E2=80=99. --=-=-= Content-Type: text/plain; charset=utf-8 Content-Disposition: inline; filename=qemu-animated-gif.scm Content-Transfer-Encoding: quoted-printable Content-Description: the code ;; Copyright =C2=A9 2020 Ludovic Court=C3=A8s ;; Released under the GNU General Public License, version 3 or later. (use-modules (ice-9 match) (gnu system vm) (gnu system install) (guix) (guix ui) (gnu packages virtualization)) (define O_CLOEXEC ;missing in Guile 3.0.2 #o02000000) (define wait-for-monitor-prompt (@@ (gnu build marionette) wait-for-monitor-prompt)) (define (spawn command) (match (primitive-fork) (0 (dynamic-wind (const #t) (lambda () (apply execl (car command) command)) (lambda () (primitive-_exit 42)))) (pid pid))) (define (shoot-movie) (mlet* %store-monad ((image (system-disk-image installation-os #:disk-image-size 'guess)) (qemu (lower-object qemu)) (_ (built-derivations (list qemu image)))) (define disk (begin (system* (string-append (derivation->output-path qemu) "/bin/qemu-img") "create" "-f" "qcow2" "/tmp/disk.img" "2G") "/tmp/disk.img")) (define command (list (string-append (derivation->output-path qemu) "/bin/qemu-system-x86_64") "-enable-kvm" "-m" "512" "-drive" (string-append "file=3D" (pk (derivation->output-path image)) ",if=3Dvirtio,cache=3Dwriteback,readonly") "-monitor" "unix:/tmp/monitor" "-drive" "file=3D/tmp/disk.img,if=3Dvirtio" "-snapshot")) (define monitor (socket AF_UNIX SOCK_STREAM 0)) (bind monitor AF_UNIX "/tmp/monitor") (listen monitor 1) (fcntl monitor F_SETFL (logior O_CLOEXEC (fcntl monitor F_GETFL))) (let ((pid (spawn command))) (match (accept monitor) ((sock . _) (wait-for-monitor-prompt sock #:quiet? #f) (let loop ((n 0)) (format sock "screendump /tmp/qemu-movie-~4,48d.ppm~%" n) (force-output sock) (wait-for-monitor-prompt sock #:quiet? #f) (usleep 200000) (loop (+ 1 n)))))))) (false-if-exception (delete-file "/tmp/monitor")) (with-build-handler (build-notifier) (with-store store (run-with-store store (shoot-movie)))) --=-=-=--