Giter Club home page Giter Club logo

web-gphoto2's Introduction

Web-gPhoto2

A gPhoto2 implementation using WebAssembly to control DSLR cameras from the browser.

Powered by a custom fork of libgphoto2, the WebUSB backend of libusb, and WebAssembly via Emscripten.

Installation

npm install web-gphoto2

Usage

A short example on how to use this package:

import { Camera } from "web-gphoto2";

let camera = new Camera();

// Triggers the browser's native USB picker listing all connected cameras.
await Camera.showPicker();

// Connects to the camera exposed in the previous step.
// In the future we might allow to connect to multiple cameras by passing a specific instance.
await camera.connect();

console.log("Operations supported by the camera:", await camera.getSupportedOps());

console.log("Current configuration tree:", await camera.getConfig());

// Update camera configuration by the setting's name.
await camera.setConfigValue("iso", "800");

// Capture a lower-quality preview frame, useful for high-FPS live view stream.
// Returns a Blob with image mime type and contents.
const blob = await camera.capturePreviewAsBlob();
// Use `URL.createObjectURL` to create an image URL from the blob or `createImageBitmap` to decode it directly.
const img = new Image();
img.src = URL.createObjectURL(blob);

// Capture a full-resolution image in format currently selected on the camera (JPEG or RAW).
// This can be used in the same way as Blob above, but also has extra information such as filename useful for download.
const file = await camera.captureImageAsFile();
const a = document.createElement("a");
a.href = URL.createObjectURL(file);
a.download = file.name;

Demo

This repository also contains a demo app running gPhoto2 on the Web: A picture of DSLR camera connected via a USB cable to a laptop. The laptop is running the Web demo mentioned in the article, which mirrors a live video feed from the camera as well as allows to tweak its settings via form controls.

For the detailed technical write-up, see the official blog post. To see the demo in action, visit the hosted version here (but make sure to read the cross-platform compatibility notes first).

If you don't have a DSLR, you can check out a recording of the demo below:

4MUKvJhKOPK2CSTkhnEC.1.mp4

Building

To build the WebAssembly part of the repo, you'll need Docker on Linux (WSL works too) or macOS machine. Then:

npm run build:wasm # runs build in Docker

If you are just updating the JS library (src/camera.ts), then it's enough to do

npm run build:ts

on any system as Wasm parts are committed to this repo.

To serve the demo, run:

npx serve examples/preact # starts a local server with COOP/COEP

Then, navigate to http://localhost:3000/ in Chrome.

Common Issues

SharedArrayBuffer can not be found SharedArrayBuffer has been disabled across all browsers due to the Spectre vulnerability. This package uses SharedArrayBuffer to communicate with the WebAssembly module. To work around this issue, you need to set two response headers for your document:
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp

Information from Stackoverflow

Error: Not found: /node_modules/.vite/deps/libapi.wasm Vite tries to optimize the dependencies by default. This causes the WebAssembly module to be moved to a different location. To prevent this, you need to exclude the web-gphoto2 package from the optimization.

In vite, both of the above mentioned issues are solved by adding the following to your vite.config.js:

import { sveltekit } from "@sveltejs/kit/vite";
import { defineConfig } from "vite";

/** @type {import('vite').Plugin} */
const viteServerConfig = {
  name: "add headers",
  configureServer: (server) => {
    server.middlewares.use((req, res, next) => {
      res.setHeader("Cross-Origin-Opener-Policy", "same-origin");
      res.setHeader("Cross-Origin-Embedder-Policy", "require-corp");
      next();
    });
  },
};

export default defineConfig({
  plugins: [sveltekit(), viteServerConfig],
  optimizeDeps: {
    exclude: ["web-gphoto2"],
  },
});

See also

RReverser/eos-remote-web - my other project for controlling Canon cameras over Web Bluetooth.

License

Like the dependencies, this demo is licensed under LGPL v2.1.

web-gphoto2's People

Contributors

icheered avatar rreverser avatar wormss avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

web-gphoto2's Issues

RuntimeError: Memory access out of bounds

When I call the "camera.CaptureImageAsFile()" method, occasionally thrown the following error:

RuntimeError: Memory access out of bounds

How can I solve this problem?

Camera: Canon 700D

Porting to NPM package

First of all: Awesome project. This is exactly the type of application that I hoped would be made possible by the introduction of WASM.

Now onto the question: I read that you're no longer supporting this project but it is still quite capable in its current version. I have never done it before, but would it technically be possible to turn this into an NPM package? I have very little experience with WASM or the other tools you used to built this application, but I imagine this would be quite popular with other programming photographers.

Cannot stop live-view after starting it

Camera: Nikon D5300

When starting the viewfinder (live-view) the camera raises the mirror and you can capturePreviewAsBlob at high speed. When trying to disable the viewfinder it will error:

Error: libapi.mjs?v=263350c0:9 Uncaught (in promise) Error: I/O in progress

My first guess is that it has something to do with the scheduling of events like @RReverser mentions in his blog.

Notes

  1. I can still change other settings like ISO while in liveview.
  2. Using the gphoto2 CLI I can enable and disable liveview as normal
  3. Updating libgphoto2 to the latest version does not fix the issue

Build Issue with Angular v13 - Node JS v14.18.2 - TS v4.6.4 - NPM Error

camera-controller.ts

image

On "ng-build",
Getting the Following Error in the File where Camera has been imported from "web-gphoto2"

image

node_modules/web-gphoto2/package.json

image

Node JS - v14.18.2

package.json

"@types/emscripten": "^1.39.10"
"typescript": "~4.6.4"
"web-gphoto2": "^0.4.1"

tsconfig.json

image

Please do help on how to resolve this issue!

Cannot reconnect after disconnecting

Code to reproduce the issue

This is the minimal (Svelte) reproduction:

<script lang="ts">
	import { Camera } from 'web-gphoto2';

	let camera = new Camera();

	async function connect() {
		console.log('Connecting to camera');
		await Camera.showPicker();
		console.log('Camera picked');
		await camera.connect();
		console.log('Connected to camera');
	}

	async function disconnect() {
		await camera.disconnect();
		console.log('Disconnected from camera');
	}
</script>

<button on:click={connect} on:keydown={connect}> Connect </button>
<button on:click={disconnect} on:keydown={disconnect}> Disconnect </button>

Steps to reproduce the issue:

Basic

  1. Click connect and pick the camera
  2. Click disconnect
  3. Click connect and pick the camera
  4. Crash

Full

  1. Click connect
  2. Console: Connecting to camera
  3. Select the camera from the device picker
  4. Console: Camera picked
  5. Console: Connected to camera
  6. Click disconnect
  7. Console: Disconnected from camera
  8. Click connect
  9. Console: Connecting to camera
  10. Select the camera from the device picker
  11. Console: Camera picked
  12. Console Error: Bindingerror
Console Error: BindingError (Click for full log) { "name": "BindingError", "message": "Cannot use deleted val. handle = 0", "stack": "BindingError: Cannot use deleted val. handle = 0\n at Error. (http://localhost:5173/node_modules/web-gphoto2/build/libapi.mjs?v=a6df64ee:9:103581)\n at new (http://localhost:5173/node_modules/web-gphoto2/build/libapi.mjs?v=a6df64ee:9:103398)\n at throwBindingError (http://localhost:5173/node_modules/web-gphoto2/build/libapi.mjs?v=a6df64ee:9:104022)\n at Object.toValue (http://localhost:5173/node_modules/web-gphoto2/build/libapi.mjs?v=a6df64ee:9:132432)\n at __emval_get_property (http://localhost:5173/node_modules/web-gphoto2/build/libapi.mjs?v=a6df64ee:9:144427)\n at http://localhost:5173/node_modules/web-gphoto2/build/libapi.wasm:wasm-function[189]:0xb47e\n at http://localhost:5173/node_modules/web-gphoto2/build/libapi.wasm:wasm-function[1183]:0x8b5f8\n at http://localhost:5173/node_modules/web-gphoto2/build/libapi.wasm:wasm-function[402]:0x2b342\n at http://localhost:5173/node_modules/web-gphoto2/build/libapi.wasm:wasm-function[1223]:0x90fd8\n at http://localhost:5173/node_modules/web-gphoto2/build/libapi.wasm:wasm-function[2090]:0x11c09d" }
  1. Console Error: Memory access out of bounds
Console Error: RuntimeError: memory access out of bounds (Click for full log) Uncaught (in promise) RuntimeError: memory access out of bounds at libapi.wasm:0xe8f9d at ret. (libapi.mjs?v=a6df64ee:9:125609) at Object.doRewind (libapi.mjs?v=a6df64ee:9:126898) at libapi.mjs?v=a6df64ee:9:127491

How to use in NuxtJS?

Hello how to use this library in NuxtJS? I'm using NuxtJS without typescript

"nuxt": "^2.15.8",

Always got error

ERROR  in ./node_modules/web-gphoto2/build/camera.js                                                                                   

Module parse failed: Unexpected character '#' (31:2)                                                                                  
File was processed with these loaders:
 * ./node_modules/babel-loader/lib/index.js
You may need an additional loader to handle the result of these loaders.
| let ModulePromise;
| export class Camera {
>   #queue = Promise.resolve();
|   #context = null;
|   static async showPicker() {

What still works?

Hey, thanks for putting this project together. It seems like a lot of stuff may have bitrotted and no longer works. Can you please help point me in the right direction to begin fixing any portion of this project?

  1. Your website demo displays the following error in Chrome Developer tools: "Error with Permissions-Policy header"

  2. Building this project by running ./build.sh leads to autoconf errors

./configure: line 4408: LT_INIT: command not found
./configure: line 4409: syntax error near unexpected token `Windows'
./configure: line 4409: `LT_LANG(Windows Resource)'
make: *** [Makefile:40: deps/libusb/Makefile] Error 2
make: *** Waiting for unfinished jobs....
autoreconf: running: aclocal --force -I auto-m4 -I gphoto-m4
autoreconf: running: libtoolize --copy --force
libtoolize: putting auxiliary files in AC_CONFIG_AUX_DIR, 'auto-aux'.
libtoolize: copying file 'auto-aux/ltmain.sh'
libtoolize: putting macros in AC_CONFIG_MACRO_DIRS, 'auto-m4'.
libtoolize: copying file 'auto-m4/libtool.m4'
libtoolize: copying file 'auto-m4/ltoptions.m4'
libtoolize: copying file 'auto-m4/ltsugar.m4'
libtoolize: copying file 'auto-m4/ltversion.m4'
libtoolize: copying file 'auto-m4/lt~obsolete.m4'
autoreconf: running: /usr/bin/autoconf --force
autoreconf: running: /usr/bin/autoheader --force
autoreconf: running: automake --add-missing --copy --force-missing
configure.ac:73: installing 'auto-aux/compile'
configure.ac:13: installing 'auto-aux/missing'
Makefile.am: installing 'auto-aux/depcomp'
autoreconf: Leaving directory `libgphoto2_port'
libtoolize: putting auxiliary files in AC_CONFIG_AUX_DIR, 'auto-aux'.
libtoolize: copying file 'auto-aux/ltmain.sh'
libtoolize: putting macros in AC_CONFIG_MACRO_DIRS, 'auto-m4'.
libtoolize: copying file 'auto-m4/libtool.m4'
libtoolize: copying file 'auto-m4/ltoptions.m4'
libtoolize: copying file 'auto-m4/ltsugar.m4'
libtoolize: copying file 'auto-m4/ltversion.m4'
libtoolize: copying file 'auto-m4/lt~obsolete.m4'
configure.ac:110: installing 'auto-aux/compile'
configure.ac:17: installing 'auto-aux/missing'
camlibs/Makefile.am: installing 'auto-aux/depcomp'
autoreconf: Leaving directory `.'
rm deps/libgphoto2/configure
emmake: error: 'make -j8' failed (returned 2)
  1. Libusb fails to run in Chrome. Many functions and vals don't resolve or throw exceptions like "caller is not a function"

Is there any way to get any of these libraries or demos to work again?

Uncaught (in promise) DOMException: Failed to execute 'requestDevice' on 'USB': No device selected.

i tried the app on the web directly, but i got an error! I using my canon 200D

libapi.mjs:9 DOMException: Failed to execute 'open' on 'USBDevice': Access denied.
(anonymous) @ libapi.mjs:9
index.js:85 Error: I/O problem
at throw_msg (libapi.mjs:9:18313)
at libapi.wasm:0xe8f33
at ret. (libapi.mjs:9:129379)
at invoke_vi (libapi.mjs:9:195627)
at libapi.wasm:0x10f946
at libapi.wasm:0xe8f33
at ret. (libapi.mjs:9:129379)
at invoke_vi (libapi.mjs:9:195627)
at libapi.wasm:0xe0271
at libapi.wasm:0xe8fd8
tryToConnectToCamera @ index.js:85
DevTools failed to load source map: Could not load content for chrome-extension://hnmpcagpplmpfojmgmnngilcnanddlhb/browser-polyfill.min.js.map: System error: net::ERR_BLOCKED_BY_CLIENT
DevTools failed to load source map: Could not load content for https://unpkg.com/[email protected]/dist/preact.module.js.map: System error: net::ERR_BLOCKED_BY_RESPONSE
web-gphoto2.rreverser.com/:1 Uncaught (in promise) {message: 'A listener indicated an asynchronous response by r…age channel closed before a response was received'}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.