Replay.jl icon indicating copy to clipboard operation
Replay.jl copied to clipboard

Can this package also store the recording to a video file?

Open rikhuijzer opened this issue 3 years ago • 18 comments

I just tested the package and got it to work. It was replaying my script perfectly fine. However, do I need manually to record my screen? Can this package also create a video file for me?

rikhuijzer avatar Jan 05 '22 12:01 rikhuijzer

Hi, @rikhuijzer. I'm very glad to hear your script works perfectly!! 😄 .

However, do I need manually to record my screen?

Yes, this Replay.jl package currently only support just replay.

Can this package also create a video file for me?

That makes sense to me. However, I have no idea how do we achieve our wish... 💦 I wish I could...

Are there any tools (including out of JuliaLang world) that have this functionality ???

terasakisatoshi avatar Jan 16 '22 07:01 terasakisatoshi

It would be cool to get this package to work with https://asciinema.org/ (Linux, macOS and *BSD only). This should be doable to add by using Julia's artifacts system. If I'm not mistaken, the artifacts system will only throw an error if you call the artifact, so an extra function could be added to this package which works on Linux and macOS and throws an error on Windows.

Unfortunately, I don't have time to implement this currently, so I'll close this issue.

rikhuijzer avatar Jan 16 '22 09:01 rikhuijzer

@rikhuijzer How about this script? It captures a screenshot that surrounds a window you specified and displays its result via OpenCV continuously. If you wanna record them as a video data, see this SO.

"""
$ pip3 install pyautogui pygetwindow opencv-python numpy
$ python record.py # <--- this file
$ # then click terminal window that runs julia
"""

import cv2
import numpy as np
import pyautogui
import pygetwindow as gw

realW, realH = pyautogui.screenshot().size
szW, szH = pyautogui.size()

while True:
    aW = realW / szW  # aspect ratio of width
    aH = realH / szH  # aspect ratio of height
    window_name = gw.getActiveWindow()
    x, y, w, h = gw.getWindowGeometry(
        window_name
    )
    region = (aW * x, aH * y, aW * w, aH * h)
    frame = np.array(
        pyautogui.screenshot(region=region)
    )
    frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
    cv2.imshow("screenshot", frame)
    if cv2.waitKey(1) == ord("q"):
        break

cv2.destroyAllWindow()

terasakisatoshi avatar Jan 16 '22 12:01 terasakisatoshi

https://asciinema.org/ is more specifically aimed at capturing terminals and therefore produces more efficient output. Also, it would be easier to maintain when something is implemented in Julia instead of depending of all kinds of Python packages

rikhuijzer avatar Jan 16 '22 12:01 rikhuijzer

🤔 I'm not sure we really need Julia's artifacts system to use functionality such as asciinema rec? brew install asciinema is fine for macOS users for example.

terasakisatoshi avatar Jan 16 '22 12:01 terasakisatoshi

If you use the artifacts system, people don’t have to manually install the dependency and you don’t get issues from people saying that things don’t work where it turns out that they are using a different version than what you have been using

rikhuijzer avatar Jan 16 '22 12:01 rikhuijzer

If you use the artifacts system, people don’t have to manually install the dependency and you don’t get issues from people saying that things don’t work where it turns out that they are using a different version than what you have been using

Yes, you're right.

Unfortunately, I don't have time to implement this currently

same for me 😅 .

I hope someone implements to solve this issue 🥇

terasakisatoshi avatar Jan 16 '22 12:01 terasakisatoshi

There is yet another solution: that is using termynal

terasakisatoshi avatar Jan 16 '22 12:01 terasakisatoshi

asciinema can install via pip install asciinema https://pypi.org/project/asciinema/ . Therefore you only have to prepare Python environment or Conda.jl whatever. Sending PR to Yggdrasil is too exaggerated for me.

terasakisatoshi avatar Jan 16 '22 12:01 terasakisatoshi

Sending PR to Yggdrasil is too exaggerated for me.

Nice. You get it! You can also add artifacts without Yggdrasil. For example, see https://github.com/JuliaBooks/Books.jl/blob/main/Artifacts.toml.

rikhuijzer avatar Jan 16 '22 13:01 rikhuijzer

Hmm I don't see Asciinema releasing binaries in their GitHub releases. Yggdrasil is the only way to go then unfortunately. Or manually create a repo with the binary outputs.

rikhuijzer avatar Jan 16 '22 13:01 rikhuijzer

I guess brew install would be the best then yes. You were right

rikhuijzer avatar Jan 16 '22 13:01 rikhuijzer

From my understanding, asciinema is written in Python https://github.com/asciinema/asciinema, therefore it is natural for me to prepare a Python environment e.g. via Conda.jl to install asciinema for those who are not macOS users or those who dislike brew

image

terasakisatoshi avatar Jan 16 '22 13:01 terasakisatoshi

@rikhuijzer could you test out the following instructions?

  1. Install Julia
  2. Install Replay.jl (make sure you've installed Replay.jl v0.3.0)
  3. Install asciinema see https://asciinema.org/docs/installation
  4. run mkdir -p ~/tmp/workspace && cd ~/tmp/workspace
  5. create file named config and add the following content
[record]
command = julia -e 'using Replay; include(joinpath(dirname(dirname(pathof(Replay))), "examples", "helloworld", "app.jl"))'

See https://asciinema.org/docs/config to learn more about Configuration file

  1. set environment variable via
$ export ASCIINEMA_CONFIG_HOME=$PWD
$ echo  $ASCIINEMA_CONFIG_HOME # just make sure it is set
~/tmp/workspace
  1. run asciinema rec record.cast
  2. run asciinema play record.cast <--- I think this is what you want.

You'll see something like:

image

terasakisatoshi avatar Jan 16 '22 13:01 terasakisatoshi

Yes that works great!

Fully automated version:

using Pkg: Pkg
dir = mktempdir()

cd(dir)
Pkg.activate(dir)
Pkg.add("Replay")

using Replay

path = joinpath(pkgdir(Replay), "examples", "helloworld", "app.jl")

text = """
    [record]
    command = julia --project -e 'using Replay; include("$path")'
    """
write("config", text)

record = `asciinema rec record.cast`

withenv("ASCIINEMA_CONFIG_HOME" => pwd()) do
    run(record)
end

out_path = joinpath(homedir(), "Downloads", "record.cast")

println("")
println("Writing file to $out_path")
println("To play it, use `asciinema play $out_path`")
cp("record.cast", out_path; force=true)
nothing

rikhuijzer avatar Jan 16 '22 19:01 rikhuijzer

I think it's worth doing reopen this issue.

terasakisatoshi avatar Jan 17 '22 06:01 terasakisatoshi

It seems there is --command option, which means we do not have to create config file manually.

terasakisatoshi avatar Jan 17 '22 06:01 terasakisatoshi

Hi @rikhuijzer

I've created QuartzGetWindow.jl which gives a julia package for obtaining GUI information for macOS users. If you use macOS device as a daily use, this package will help you. 😄

↓↓↓ Usage

% git clone https://github.com/terasakisatoshi/QuartzGetWindow.jl.git
% cd QuartzGetWindow
% cat examples/demo.jl
using Dates

using Replay

using QuartzGetWindow

function takemov()
    x, y, w, h = getWindowGeometry(getActiveWindow())
    file = "$(Dates.now()).mov"
    run(`screencapture -R$(x),$(y),$(w),$(h) -v $(file)`)
end

function record()
    instructions = [
        "println(\"Hello QuartzGetWindow!!!\")",
        """
        for i in 1:5
            sleep(0.1)
            println(i)
        end
        println("Done")
        """,
    ]
    @async takemov()
    replay(instructions)
    exit()
end

record()
% julia examples/demo.jl

↓↓↓Result

https://user-images.githubusercontent.com/16760547/164014359-257d6c48-a952-4a9a-8568-6b16d6bfe0ab.mov

terasakisatoshi avatar Apr 19 '22 13:04 terasakisatoshi