Skip to content

Commit

Permalink
feat: mac screenshot fast
Browse files Browse the repository at this point in the history
  • Loading branch information
lihuakun committed Jul 19, 2023
1 parent 758b0bf commit 0ea40fa
Show file tree
Hide file tree
Showing 10 changed files with 123 additions and 56 deletions.
2 changes: 1 addition & 1 deletion examples/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"start": "npm run dev"
},
"dependencies": {
"akey-electron-screenshots": "/Users/ansiyuan/Documents/ansiyuan/packages/screenshots/packages/electron-screenshots",
"akey-electron-screenshots": "1.0.16-beta.5",
"akey-react-screenshots": "/Users/ansiyuan/Documents/ansiyuan/packages/screenshots/packages/react-screenshots",
"check-disk-space": "^3.4.0",
"electron-log": "^4.4.8",
Expand Down
3 changes: 2 additions & 1 deletion examples/publishElectron.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ electron_screenshot=$home"/packages/electron-screenshots"


cd $electron_screenshot
yarn add [email protected]
yarn add [email protected]
yarn add [email protected]

npm publish --tag beta
2 changes: 2 additions & 0 deletions examples/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ home=$(pwd)

react_screenshot=$home"/packages/react-screenshots"
electron_screenshot=$home"/packages/electron-screenshots"
desktop_screenshot=$home"/packages/screenshot-desktop"
example=$home"/examples"

echo $react_screenshot
yarn build

cd $electron_screenshot
yarn add $react_screenshot
yarn add $desktop_screenshot
yarn build


Expand Down
3 changes: 0 additions & 3 deletions examples/src/main/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,6 @@ app.whenReady().then(() => {
screenshotsIns.on('ok', (e, buffer, bounds) => {
const image = nativeImage.createFromBuffer(buffer)
mainWindow.webContents.send('screenshot:ok', { url: image.toDataURL() })

console.log('screenshots buffer', buffer)
console.log('screenshots image', image.toDataURL())
})

globalShortcut.register('Escape', () => {
Expand Down
27 changes: 15 additions & 12 deletions examples/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2429,24 +2429,27 @@ ajv@^6.10.0, ajv@^6.12.0, ajv@^6.12.5:
json-schema-traverse "^0.4.1"
uri-js "^4.2.2"

akey-electron-screenshots@/Users/ansiyuan/Documents/ansiyuan/packages/screenshots/packages/electron-screenshots:
version "1.0.1-5.1"
[email protected]:
version "1.0.16-beta.5"
resolved "https://registry.npmjs.org/akey-electron-screenshots/-/akey-electron-screenshots-1.0.16-beta.5.tgz#405b0927fe532b474d7a28f35045510c0b86207d"
integrity sha512-zPnA+SMBVmJK4IH8XxkwnNuYPmll/22rhaOQlpgZpca9JV9ussKy9BQVyREpRB6qI4NXtCYq83ZwtYtGm6yZZw==
dependencies:
akey-react-screenshots "file:../packages/react-screenshots"
akey-react-screenshots "1.0.16-beta.3"
akey-screenshot-desktop "1.14.3"
debug "^4.3.3"
fs-extra "^10.1.0"
screenshot-desktop "^1.12.7"

"akey-electron-screenshots@file:../packages/electron-screenshots":
version "1.0.1-5.1"
dependencies:
akey-react-screenshots "file:../packages/react-screenshots"
debug "^4.3.3"
fs-extra "^10.1.0"
screenshot-desktop "^1.12.7"
[email protected], "akey-react-screenshots@file:../packages/react-screenshots":
version "1.0.16-beta.3"

"akey-react-screenshots@file:../packages/react-screenshots":
version "1.0.15"
[email protected]:
version "1.14.3"
resolved "https://registry.npmjs.org/akey-screenshot-desktop/-/akey-screenshot-desktop-1.14.3.tgz#e1f8dc226cb90cca19cfa226ea29c26e2add2fce"
integrity sha512-aAqtGCmrSywhfuBHxhJqsLDmPB5xBdbTNTHriv8tj4/JJGjTKZexs36W4bJ79wYeg2p2z6VJfL/Flw1WDEBRvA==
dependencies:
pinkie-promise "^2.0.1"
temp "^0.9.4"

ansi-html-community@^0.0.8:
version "0.0.8"
Expand Down
8 changes: 4 additions & 4 deletions packages/electron-screenshots/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "akey-electron-screenshots",
"version": "1.0.16",
"version": "1.0.16-beta.5",
"description": "electron 截图插件",
"types": "lib/screenshots.d.ts",
"main": "lib/screenshots.js",
Expand Down Expand Up @@ -35,10 +35,10 @@
"registry": "https://registry.npmjs.org/"
},
"dependencies": {
"akey-react-screenshots": "/Users/ansiyuan/Documents/ansiyuan/packages/screenshots/packages/react-screenshots",
"akey-react-screenshots": "1.0.16-beta.3",
"akey-screenshot-desktop": "1.14.3",
"debug": "^4.3.3",
"fs-extra": "^10.1.0",
"screenshot-desktop": "^1.12.7"
"fs-extra": "^10.1.0"
},
"peerDependencies": {
"electron": ">=14"
Expand Down
9 changes: 6 additions & 3 deletions packages/electron-screenshots/src/getDisplay.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import { Rectangle, screen } from 'electron'
import screenshot from 'screenshot-desktop'

export interface Display extends Rectangle {
id: number
screenshotDesktopId?: number // 截图包screenshot-desktop需要用到
index?: number
}

export interface ScreenshotDesktopDisplay {
id: number;
name: string;
}

/**
*
* @returns screenshotDesktopDisplays
Expand Down Expand Up @@ -43,9 +47,8 @@ export interface Display extends Rectangle {
]
*
*/
export const getAllDisplays = async () => {
export const getAllDisplays = async (screenshotDesktopDisplays: ScreenshotDesktopDisplay[]) => {
const displays = screen.getAllDisplays()
const screenshotDesktopDisplays = await screenshot.listDisplays()
return displays.map(({ bounds, id }, index) => {
return {
id,
Expand Down
101 changes: 78 additions & 23 deletions packages/electron-screenshots/src/screenshots.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ import {
import Events from 'events'
import fs from 'fs-extra'
import path from 'path'
import screenshot from 'screenshot-desktop'
import Event from './event'
import getDisplay, { Display, getAllDisplays } from './getDisplay'
import getDisplay, { Display, getAllDisplays, ScreenshotDesktopDisplay } from './getDisplay'
import padStart from './padStart'
import { Bounds, ScreenshotsData } from './preload'
import akeyScreenshotDesktop from 'akey-screenshot-desktop'

export type LoggerFn = (...args: unknown[]) => void
export type Logger = Debugger | LoggerFn
Expand Down Expand Up @@ -51,8 +51,12 @@ export class Screenshots extends Events {
// 截图窗口对象
public $wins: BrowserWindow[] = []

// electron screen 获取到的屏幕信息
public displays: Display[] = []

// akey-screenshot-desktop 获取到的屏幕信息
public screenshotDesktopDisplays: ScreenshotDesktopDisplay[] = []

public $views: BrowserView[] = []

/* 截图矩形标识器(ScreenshotsCanvas)所在屏幕序号index, 默认是-1,表示当前没有进行截图圈选 */
Expand All @@ -64,7 +68,10 @@ export class Screenshots extends Events {

private screenshotPath: string

private isReady = new Promise<void>((resolve) => {
private status: 'ready' | 'busy' | 'wait' = 'wait' // 当前截图组件状态,只有ready的时候允许截图

// web也要准备好后才能操作,包括双击和圈选
private isWebReady = new Promise<void>((resolve) => {
ipcMain.once('SCREENSHOTS:ready', () => {
this.logger('SCREENSHOTS:ready')

Expand All @@ -81,19 +88,41 @@ export class Screenshots extends Events {
}
this.singleWindow = opts?.singleWindow || false
this.screenshotPath = path.join(app.getPath('userData'), '/AkeyTemp')
console.time('ensureDirSync')
fs.ensureDirSync(this.screenshotPath)
console.timeEnd('ensureDirSync')
this.listenIpc()
this.refreshViews()
.then(() => this.setReady())
if (opts?.lang) {
this.setLang(opts.lang)
}
}

private setReady () {
this.status = 'ready'
this.logger('Screenshots:status', this.status)
}

private setBusy () {
this.status = 'busy'
this.logger('Screenshots:status', this.status)
}

private setWait () {
this.status = 'wait'
this.logger('Screenshots:status', this.status)
}

private isReady () {
return this.status === 'ready'
}

// 根据屏幕数量预加载BrowserView
// 初始化displays和$views
private async refreshViews () {
this.displays = await getAllDisplays()
console.log('getAllDisplays', this.displays)
this.screenshotDesktopDisplays = await akeyScreenshotDesktop.listDisplays()
this.displays = await getAllDisplays(this.screenshotDesktopDisplays)
this.$views = this.displays.map((display) => {
const browserView = new BrowserView({
webPreferences: {
Expand Down Expand Up @@ -137,7 +166,9 @@ export class Screenshots extends Events {
}

return Promise.all(this.displays.map(async (display, i) => {
console.time('desktopCapture')
const imageUrl = await this.capture(display)
console.timeEnd('desktopCapture')

try {
await this.createWindow(display, i)
Expand Down Expand Up @@ -166,8 +197,17 @@ export class Screenshots extends Events {
return
}

this.logger(`startCapture:status is ${this.status}`)

if (!this.isReady()) {
return
}

this.setBusy()

this.boundsDisplayIndex = -1

await this.isWebReady
await this.createWindowForDisplays(options)

console.timeEnd('startCapture')
Expand All @@ -181,6 +221,7 @@ export class Screenshots extends Events {
await this.reset()

if (!this.$wins.length) {
this.setReady()
return
}

Expand Down Expand Up @@ -210,6 +251,7 @@ export class Screenshots extends Events {
}

fs.emptyDir(this.screenshotPath)
this.setReady()
}

/**
Expand All @@ -218,7 +260,7 @@ export class Screenshots extends Events {
public async setLang (lang: Partial<Lang>): Promise<void> {
this.logger('setLang', lang)

await this.isReady
await this.isWebReady

// this.$views.webContents.send('SCREENSHOTS:setLang', lang)
this.$views.forEach((win) =>
Expand All @@ -236,16 +278,18 @@ export class Screenshots extends Events {

private async reset () {
this.logger('reset')
if (this.$views.length > 0) {
// 重置截图区域
this.$views.forEach((view) => view.webContents.send('SCREENSHOTS:reset'))

// 保证 UI 有足够的时间渲染
await Promise.race([
new Promise<void>((resolve) => setTimeout(() => resolve(), 500)),
new Promise<void>((resolve) =>
ipcMain.once('SCREENSHOTS:reset', () => resolve())
)
])
this.$views.forEach((view) => view.webContents.send('SCREENSHOTS:reset'))

// 保证 UI 有足够的时间渲染
await Promise.race([
new Promise<void>((resolve) => setTimeout(() => resolve(), 500)),
new Promise<void>((resolve) =>
ipcMain.once('SCREENSHOTS:reset', () => resolve())
)
])
}
}

/**
Expand Down Expand Up @@ -342,7 +386,7 @@ export class Screenshots extends Events {
height: display.height
})

this.$views[index].webContents.openDevTools()
// this.$views[index].webContents.openDevTools()

win.show()

Expand All @@ -353,10 +397,11 @@ export class Screenshots extends Events {

private async capture (display: Display): Promise<string> {
const filename = path.join(this.screenshotPath, `/shot-${Date.now()}.png`)
this.logger('SCREENSHOTS:capture', display, filename)
this.logger('SCREENSHOTS:cmd:capture', display, filename)

const imgPath = await screenshot({
const imgPath = await akeyScreenshotDesktop({
screen: display.screenshotDesktopId,
displays: this.screenshotDesktopDisplays,
filename
})

Expand All @@ -375,10 +420,9 @@ export class Screenshots extends Events {

const event = new Event()
this.emit('ok', event, buffer, data)
if (event.defaultPrevented) {
return
if (!event.defaultPrevented) {
clipboard.writeImage(nativeImage.createFromBuffer(buffer))
}
clipboard.writeImage(nativeImage.createFromBuffer(buffer))
this.endCapture()
})
/**
Expand Down Expand Up @@ -427,7 +471,13 @@ export class Screenshots extends Events {

const event = new Event()
this.emit('save', event, buffer, data)
if (event.defaultPrevented || !this.$wins.length) {
if (event.defaultPrevented) {
this.endCapture()
return
}

if (!this.$wins.length) {
this.endCapture()
return
}

Expand All @@ -447,6 +497,7 @@ export class Screenshots extends Events {
})

if (!win) {
this.endCapture()
return
}
// win.setAlwaysOnTop(true)
Expand All @@ -467,6 +518,8 @@ export class Screenshots extends Events {

screen.on('display-added', async () => {
// 屏幕变化期间不允许截图
this.setWait()

this.emit('screenchangestart')
try {
this.logger('display-added')
Expand All @@ -476,12 +529,13 @@ export class Screenshots extends Events {
} catch (e: any) {
this.logger(`display-added-error ${e.message}`)
}

this.emit('screenchangeend')
this.setReady()
})

screen.on('display-removed', async () => {
// 屏幕变化期间不允许截图
this.setWait()
this.emit('screenchangestart')
try {
this.logger('display-removed')
Expand All @@ -492,6 +546,7 @@ export class Screenshots extends Events {
this.logger(`display-removed-error ${e.message}`)
}
this.emit('screenchangeend')
this.setReady()
})
}
}
Loading

0 comments on commit 0ea40fa

Please sign in to comment.