I wanted to capture only certain window using Imagemagick or Ffmpeg, but I heard that the x11 id needed for that is not supported on Mac.
The purpose is to capture the application window so that all areas are displayed even if some areas are out of the display and are not visible.
In general, applications on macOS use the native Cocoa framework to generate their GUI rather than X11. I'll write my answer to address each possibility in term, separating the two with a horizontal line.
With X11
You can install an X11 server called XQuartz on macOS using
homebrewwith:However, only applications written to the X11 interface will create XQuartz windows and you can capture those windows in an X11 way, using
xwininfoand passing theidto ImageMagick. However, relatively few apps use X11.Let's just show that quickly with an example:
Another issue is that the homebrew version of ImageMagick doesn't support X11... so you'll have to either edit the homebrew formula, or run
./configureyourself and include X11 support - which is non-trivial.With native macOS Cocoa and 'screencapture'
If your app uses the native Cocoa interface, you can get its "Cocoa id" using a script I shared here. Slightly more simply, you can run some AppleScript to get the window id, e.g. to get the id of a window belonging to the Terminal app:
You can then use that id with the
screencapturecommand supplied with macOS to hopefully do what you want with whatever application you are using. For example:With 'ffmpeg'
On macOS,
ffmpeguses AVFoundation under the covers, so first you need to get the index that AVFoundation assigns to your screen, like this:Look at the listing above and you can see that I must use device
[1]if I want to record the screen. As I don't want sound recorded, I usenonefor the sound channel, so the basicffmpegcommand to record the screen on my Mac at 30fps will be:Now, you want to record a specific window, but
ffmpegdoesn't know about windows, it only knows coordinates, so we need to find the coordinates of our window. Imagine I want to record Safari main window, first I get its location with:Now I tell
ffmpegto record that:and it appears to work, but doesn't! Apparently there's no atom and
ffplaycan't play stuff without atoms. It transpires that atoms get written at the end of the video - unless you Control-C out of them. So, you can now make sure you don't need to Control-C by adding a duration of 5 seconds:That also appears to work, but doesn't actually work either. You can play it with
ffplaybut not Apple's QuickTime which only likesyuv420pformat, so you can actually do what you want with: