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

Torch Feature Added #169

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
4 changes: 2 additions & 2 deletions docs/index.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<!DOCTYPE html><html lang="en"><head>
<meta charset="utf-8">
<title>NgxWebcam</title>
<base href="/ngx-webcam/">
<base href="./">

<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.ef46db3751d8e999.css"></head>
<body>
<approot></approot>
<script src="runtime.a281ae2b4dd178c5.js" type="module"></script><script src="polyfills.e24170126eb2c264.js" type="module"></script><script src="main.720aa27968dc5f2c.js" type="module"></script>
<script src="runtime.a281ae2b4dd178c5.js" type="module"></script><script src="polyfills.e24170126eb2c264.js" type="module"></script><script src="main.c4149889c4cdf285.js" type="module"></script>

</body></html>

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@ <h1>
[imageQuality]="1"
(cameraSwitched)="cameraWasSwitched($event)"
(initError)="handleInitError($event)"
(torchAvailable)="torchIsAvailable($event)"
[switchTorch]="switchTorchObservable"
></webcam>
<br>
<button class="actionBtn" (click)="triggerSnapshot();">Take A Snapshot</button>
<button class="actionBtn" (click)="toggleWebcam();">Toggle Webcam</button>
<button class="actionBtn" (click)="switchingTorch();" *ngIf="torchAvailable">Lantern</button>
<br>
<button class="actionBtn" (click)="showNextWebcam(true);" [disabled]="!multipleWebcamsAvailable">Next Webcam</button>
<input id="cameraSwitchCheckbox" type="checkbox" [(ngModel)]="allowCameraSwitch"><label for="cameraSwitchCheckbox">Allow Camera Switch</label>
Expand Down
15 changes: 15 additions & 0 deletions src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export class AppComponent implements OnInit {
public deviceId: string;
public facingMode: string = 'environment';
public messages: any[] = [];
public torchAvailable: boolean = false;

// latest snapshot
public webcamImage: WebcamImage = null;
Expand All @@ -25,6 +26,8 @@ export class AppComponent implements OnInit {
private trigger: Subject<void> = new Subject<void>();
// switch to next / previous / specific webcam; true/false: forward/backwards, string: deviceId
private nextWebcam: Subject<boolean|string> = new Subject<boolean|string>();
// webcam torch trigger
private switchTorch: Subject<void> = new Subject<void>();

public ngOnInit(): void {
this.readAvailableVideoInputs();
Expand Down Expand Up @@ -92,4 +95,16 @@ export class AppComponent implements OnInit {
this.multipleWebcamsAvailable = mediaDevices && mediaDevices.length > 1;
});
}

public switchingTorch(): void {
this.switchTorch.next();
}

public get switchTorchObservable(): Observable<void> {
return this.switchTorch.asObservable();
}

public torchIsAvailable($event: boolean) {
this.torchAvailable = $event;
}
}
28 changes: 28 additions & 0 deletions src/app/modules/webcam/typings/media-stream-track-ext.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
interface MediaStreamTrackExt extends MediaStreamTrack {
getCapabilities(): MediaTrackCapabilitiesExt;
}

interface MediaTrackCapabilitiesExt extends MediaTrackCapabilities {
torch?: boolean;
}

interface MediaTrackConstraintSet {
aspectRatio?: ConstrainDouble;
channelCount?: ConstrainULong;
deviceId?: ConstrainDOMString;
echoCancellation?: ConstrainBoolean;
facingMode?: ConstrainDOMString;
frameRate?: ConstrainDouble;
groupId?: ConstrainDOMString;
height?: ConstrainULong;
latency?: ConstrainDouble;
sampleRate?: ConstrainULong;
sampleSize?: ConstrainULong;
suppressLocalAudioPlayback?: ConstrainBoolean;
width?: ConstrainULong;
torch?: ConstrainBoolean;
}

interface MediaTrackConstraints extends MediaTrackConstraintSet {
advanced?: MediaTrackConstraintSet[];
}
57 changes: 57 additions & 0 deletions src/app/modules/webcam/webcam/webcam.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ export class WebcamComponent implements AfterViewInit, OnDestroy {
@Output() public imageClick: EventEmitter<void> = new EventEmitter<void>();
/** Emits the active deviceId after the active video device was switched */
@Output() public cameraSwitched: EventEmitter<string> = new EventEmitter<string>();
/** Emits the capability torch deviceId after the active video device was switched */
@Output() public torchAvailable: EventEmitter<boolean> = new EventEmitter<boolean>();

/** available video devices */
public availableVideoInputs: MediaDeviceInfo[] = [];
Expand All @@ -50,6 +52,10 @@ export class WebcamComponent implements AfterViewInit, OnDestroy {
/** If the Observable represented by this subscription emits, an image will be captured and emitted through
* the 'imageCapture' EventEmitter */
private triggerSubscription: Subscription;
/** Observable for Torch */
private switchTorchSubscription: Subscription;
/** Torch status On-Off */
private torchStatus: boolean = false;
/** Index of active video in availableVideoInputs */
private activeVideoInputIndex: number = -1;
/** Subscription to switchCamera events */
Expand Down Expand Up @@ -103,6 +109,18 @@ export class WebcamComponent implements AfterViewInit, OnDestroy {
});
}

@Input()
public set switchTorch(switchTorch: Observable<void>) {
if (this.switchTorchSubscription) {
this.switchTorchSubscription.unsubscribe();
}

// Subscribe to events from this Observable to take snapshots
this.switchTorchSubscription = switchTorch.subscribe(() => {
this.applyTorch();
});
}

/**
* Get MediaTrackConstraints to request streaming the given device
* @param deviceId
Expand Down Expand Up @@ -306,6 +324,43 @@ export class WebcamComponent implements AfterViewInit, OnDestroy {
return this.width / this.height;
}


/**
* 'torch' is not on MediaStreamTrack interface?
* Added a new definition for mediaStreamTrack
* It works in:
* Chromium browser's: running well
* Firefox: don't work (feb-2022)
* IOS: idk
*/
private isTorchAvailable(mediaStreamTrack: MediaStreamTrackExt): boolean {
try {
return mediaStreamTrack.getCapabilities().torch;
} catch (e) {
console.error('Torch is not supported in your browser: ' + (e.message || e));
}
return false;
}

private applyTorch(): void {
const track = this.getActiveVideoTrack();
const constraints = {
advanced: [{torch: !this.torchStatus}]
};
if (this.isTorchAvailable(track)) {
track.applyConstraints(constraints)
.then(() => {
this.torchStatus = !this.torchStatus;
// return track;
})
.catch((e) => {
this.initError.next(<WebcamInitError>{message: e.message});
});
} else {
alert('Not Flash');
}
}

/**
* Init webcam live view
*/
Expand All @@ -324,6 +379,8 @@ export class WebcamComponent implements AfterViewInit, OnDestroy {

this.activeVideoSettings = stream.getVideoTracks()[0].getSettings();
const activeDeviceId: string = WebcamComponent.getDeviceIdFromMediaStreamTrack(stream.getVideoTracks()[0]);
// Initial detect torch funtion
this.torchAvailable.emit(this.isTorchAvailable(stream.getVideoTracks()[0]));

this.cameraSwitched.next(activeDeviceId);

Expand Down
3 changes: 2 additions & 1 deletion src/tsconfig.app.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
},
"files": [
"main.ts",
"polyfills.ts"
"polyfills.ts",
"app/modules/webcam/typings/media-stream-track-ext.d.ts"
],
"include": [
"src/**/*.d.ts"
Expand Down