Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Video Support added for WebM MediaType #51

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Try out the <a href="https://basst314.github.io/ngx-webcam/?" target="_blank">Li
## Features
* Webcam live view
* Photo capturing
* Video capturing ((Re)Play, Finish, Pause / Resume Function)
* Smartphone compatibility for modern OS's (OS must support WebRTC/UserMedia API)
* Access to front- and back-camera, if multiple cameras exist
* Portrait & Landscape mode on smartphones
Expand Down Expand Up @@ -57,6 +58,16 @@ export class AppModule { }

`<webcam></webcam>`

4) Optionally for WebM video captuing support you need to add this to your `angular.json`:

```
...
"scripts": [
"node_modules/whammy/whammy.js"
]
...
```

As simple as that.

For more examples, see the code in the <a href="https://github.com/basst314/ngx-webcam-demo" target="_blank">Demo-Project</a>.
Expand All @@ -65,18 +76,25 @@ For more examples, see the code in the <a href="https://github.com/basst314/ngx-
This section describes the basic inputs/outputs of the component. All inputs are optional.
### Inputs
* `trigger: Observable<void>`: An `Observable` to trigger image capturing. When it fires, an image will be captured and emitted (see Outputs).
* `triggerStart: Observable<void>`: An `Observable` to trigger video capturing. When it fires, a video will be captured any captured video will be removed.
* `triggerStop: Observable<void>`: An `Observable` to trigger video finish. When it fires, the started video will be finished and emitted (see Outputs).
* `triggerPause: Observable<void>`: An `Observable` to trigger pausing / resuming video capturing. When it fires, the video will be put on hold or resumed.
* `width: number`: The maximal video width of the webcam live view.
* `height: number`: The maximal video height of the webcam live view. The actual view will be placed within these boundaries, respecting the aspect ratio of the video stream.
* `videoOptions: MediaTrackConstraints`: Defines constraints ([MediaTrackConstraints](https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints)) to apply when requesting the video track.
* `videoOptions: MediaTrackConstraints`: Defines constraints ([MediaTrackConstraints](https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints)) to apply when requesting the video track.
Note: You can request a framerate (default : 16 fps) here which will be tried to reach. Since rendering takes some time the requested framerate is possibly not reached on some devices.
* `mirrorImage: string | WebcamMirrorProperties`: Flag to control image mirroring. If the attribute is missing or `null` and a webcam claims to be user-facing, the image will be mirrored (x-axis) to provide a better user experience. A string value of `"never"` will prevent mirroring, whereas a value of `"always"` will mirror every webcam stream, even if the webcam cannot be detected as user-facing. For future extensions, the `WebcamMirrorProperties` object can also be used to set these values.
* `allowCameraSwitch: boolean`: Flag to enable/disable camera switch. If enabled, a switch icon will be displayed if multiple cameras are found.
* `switchCamera: Observable<boolean|string>`: Can be used to cycle through available cameras (true=forward, false=backwards), or to switch to a specific device by deviceId (string).
* `captureImageData: boolean = false`: Flag to enable/disable capturing of a lossless pixel ImageData object when a snapshot is taken. ImageData will be included in the emitted `WebcamImage` object.
* `imageType: string = 'image/jpeg'`: [Image type](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toDataURL) to use when capturing snapshots. Default is 'image/jpeg'.
* `frameType: string = 'image/webp'`: [Image type](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toDataURL) to use when capturing video frames. Default is 'image/webp' (only supported currently).
* `imageQuality: number = 0.92`: [Image quality](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toDataURL) to use when capturing snapshots. Must be a number between 0..1. Default is 0.92.
* `frameQuality: number = 0.92`: [Image quality](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toDataURL) to use when capturing video frames. Must be a number between 0..1. Default is 0.92.

### Outputs
* `imageCapture: EventEmitter<WebcamImage>`: Whenever an image is captured (i.e. triggered by `[trigger]`), the image is emitted via this `EventEmitter`. The image data is contained in the `WebcamImage` data structure as both, plain Base64 string and data-url.
* `videoCapture: EventEmitter<WebcamVideo>`: Whenever a video is captured (i.e. triggered by `[triggerStop]`), the video is emitted via this `EventEmitter`. The video data is contained in the `WebcamVideo` data structure as both, plain Base64 string and Blob.
* `imageClick: EventEmitter<void>`: An `EventEmitter` to signal clicks on the webcam area.
* `initError: EventEmitter<WebcamInitError>`: An `EventEmitter` to signal errors during the webcam initialization.
* `cameraSwitched: EventEmitter<string>`: Emits the active deviceId after the active video device has been switched.
Expand Down
8 changes: 6 additions & 2 deletions angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
"styles": [
"src/styles.scss"
],
"scripts": []
"scripts": [
"node_modules/whammy/whammy.js"
]
},
"configurations": {
"production": {
Expand Down Expand Up @@ -69,7 +71,9 @@
"karmaConfig": "./karma.conf.js",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.spec.json",
"scripts": [],
"scripts": [
"node_modules/whammy/whammy.js"
],
"styles": [
"src/styles.scss"
],
Expand Down
3 changes: 1 addition & 2 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@
<meta charset="utf-8">
<title>NgxWebcam</title>
<base href="/ngx-webcam/">

<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<link rel="stylesheet" href="styles.09e2c710755c8867a460.css"></head>
<body>
<appRoot></appRoot>
<script src="runtime-es2015.858f8dd898b75fe86926.js" type="module"></script><script src="polyfills-es2015.43244fb1bca8dedd392f.js" type="module"></script><script src="runtime-es5.741402d1d47331ce975c.js" nomodule></script><script src="polyfills-es5.c31392a910a7a6d6981c.js" nomodule></script><script src="main-es2015.eac224979183a4668380.js" type="module"></script><script src="main-es5.d201c182e384057a6b7e.js" nomodule></script></body>
<script src="runtime-es2015.858f8dd898b75fe86926.js" type="module"></script><script src="polyfills-es2015.c89528ac47d46bd53cb8.js" type="module"></script><script src="runtime-es5.741402d1d47331ce975c.js" nomodule></script><script src="polyfills-es5.f46364be59b8dcd3f797.js" nomodule></script><script src="scripts.43ca8c620b9b8361f037.js"></script><script src="main-es2015.ddfb83479ce4a8c39a2f.js" type="module"></script><script src="main-es5.c2c2a0f2cfabbcffa383.js" nomodule></script></body>
</html>

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions docs/main-es5.c2c2a0f2cfabbcffa383.js

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion docs/main-es5.d201c182e384057a6b7e.js

This file was deleted.

1 change: 0 additions & 1 deletion docs/polyfills-es2015.43244fb1bca8dedd392f.js

This file was deleted.

1 change: 1 addition & 0 deletions docs/polyfills-es2015.c89528ac47d46bd53cb8.js

Large diffs are not rendered by default.

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions docs/scripts.43ca8c620b9b8361f037.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

51 changes: 18 additions & 33 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@
"private": false,
"peerDependencies": {
"@angular/core": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0",
"rxjs": "^5.0.0 || ^6.0.0"
"rxjs": "^5.0.0 || ^6.0.0",
"whammy": "0.0.1"
},
"devDependencies": {
"@angular-devkit/build-angular": "^0.800.3",
Expand Down
1 change: 1 addition & 0 deletions public_api.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export * from './src/app/modules/webcam/webcam.module';
export * from './src/app/modules/webcam/webcam/webcam.component';
export * from './src/app/modules/webcam/domain/webcam-image';
export * from './src/app/modules/webcam/domain/webcam-video';
export * from './src/app/modules/webcam/domain/webcam-init-error';
export * from './src/app/modules/webcam/domain/webcam-mirror-properties';
export * from './src/app/modules/webcam/util/webcam.util';
15 changes: 14 additions & 1 deletion src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ <h1>
</h1>

<div>
<webcam [height]="500" [width]="500" [trigger]="triggerObservable" (imageCapture)="handleImage($event)" *ngIf="showWebcam"
<webcam [height]="500" [width]="500" [trigger]="triggerObservable" [triggerStart]="triggerStartObservable" [triggerStop]="triggerStopObservable" [triggerPause]="triggerPauseObservable" (imageCapture)="handleImage($event)" (videoCapture)="handleVideo($event)" *ngIf="showWebcam"
[allowCameraSwitch]="allowCameraSwitch" [switchCamera]="nextWebcamObservable"
[videoOptions]="videoOptions"
[imageQuality]="1"
Expand All @@ -13,6 +13,9 @@ <h1>
></webcam>
<br/>
<button class="actionBtn" (click)="triggerSnapshot();">Take A Snapshot</button>
<button class="actionBtn" (click)="triggerStartSnapshot();">(Re)Start video</button>
<button class="actionBtn" (click)="triggerStopSnapshot();">Finish video</button>
<button class="actionBtn" (click)="triggerPauseSnapshot();">Pause / Resume video</button>
<button class="actionBtn" (click)="toggleWebcam();">Toggle Webcam</button>
<br/>
<button class="actionBtn" (click)="showNextWebcam(true);" [disabled]="!multipleWebcamsAvailable">Next Webcam</button>
Expand All @@ -28,6 +31,16 @@ <h2>Nice one!</h2>
<img [src]="webcamImage.imageAsDataUrl"/>
</div>

<div class="snapshot" *ngIf="videoBlob">
<h2>Nice one video!</h2>

<video style="width: 300px;">
<source [src]="videoBlob" type='video/webm; codecs="vp8, vorbis"' />
</video>
<br />
<a download [href]="videoBlob">test</a>
</div>

<h4 *ngIf="errors.length > 0">Messages:</h4>
<ul *ngFor="let error of errors">
<li>{{error | json}}</li>
Expand Down
Loading