dimensional-de / napi-canon-cameras

Node AddOn Api module for Canon cameras
GNU General Public License v3.0
52 stars 21 forks source link

Electron Example #24

Open bayunvnt opened 1 month ago

bayunvnt commented 1 month ago

Hi there, first of all i want to thankyou for providing this wrapper. i'm currently using nextron to create application (next app with electron) from https://github.com/saltyshiomix/nextron but, after install .tgz file i have error "Not implemented - stub only" when i call watchCameras / any function to take picture, is there any config on electron that i must add? or someone can share an example app for using this wrapper on nextron app?

thanks before

wildangunawan commented 2 weeks ago

Can you share your repository? Make sure to call the functions/APIs from this wrapper from your main process only. Do that thru IPC from renderer to main.

Here's an example how the IPC should be: src/main/ipc/camera.ts

import {
  Camera,
  cameraBrowser,
  CameraProperty,
  CameraPropertyValue,
  FileChangeEvent,
  watchCameras,
  Option
} from '@dimensional/napi-canon-cameras'
import { app, BrowserWindow, ipcMain } from 'electron'
import { existsSync, mkdirSync, writeFile } from 'fs'

export const registerCameraIPC = (mainWindow: BrowserWindow) => {
  let camera: Camera | null = null

  ipcMain.handle('connect-to-camera', async () => {
    camera = cameraBrowser.getCamera()
    if (!camera) throw new Error('No camera found')

    camera.connect()

    camera.setProperties({
      [CameraProperty.ID.SaveTo]: Option.SaveTo.Host
    })

    camera.setEventHandler((eventName, event) => {
      // catch download request events
      if (
        eventName === Camera.EventName.FileCreate ||
        eventName === Camera.EventName.DownloadRequest
      ) {
        const file = (event as FileChangeEvent).file
        const data = 'data:image/jpeg;base64,' + file.downloadToString() // base64

        // Do whatever you want with the data
      }
    })

    watchCameras()

    console.log('Camera connected successfully')
    return camera.description
  }
}

From the renderer process, src/renderer/App.tsx (or whatever file)

// ... imports

export default function FirstLoad() {
  const connectToCamera = async () => {
    const camera_name = await window.electron.ipcRenderer.invoke('connect-to-camera')
    toast.success(`Connected to ${camera_name}!`)
  }

  useEffect(() => {
    connectToCamera()
  }, [])
}
azureai commented 1 week ago

I'm encountering the same issue. After running everything and packaging it up, I noticed that when I install the node package into my project, all the files in the path node_modules\@dimensional\napi-canon-cameras\src\stubs\camera-api are stubs and require implementation. So my app throws "Not implemented - stub only" too. Could you provide an example of how to implement these files? I'm having difficulty figuring out how to reference the .cc files when attempting the implementation.

ThomasWeinert commented 1 week ago

They are implemented in the NAPI extension. The stub files are here for TypeScript. The type definition are generated from the stubs. You can use them to access types/constants in the browser part of your application, too. The stubs are implementing some logic, just not the camera functions.

The extension is only available from the electron main process. You need to use IPC to send commands from the browser application to the electron process. Check the example @wildangunawan provided.