ngx-media 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/.agents/skills/angular-developer/SKILL.md +131 -0
  2. package/.agents/skills/angular-developer/references/angular-animations.md +160 -0
  3. package/.agents/skills/angular-developer/references/angular-aria.md +597 -0
  4. package/.agents/skills/angular-developer/references/cli.md +86 -0
  5. package/.agents/skills/angular-developer/references/component-harnesses.md +57 -0
  6. package/.agents/skills/angular-developer/references/component-styling.md +91 -0
  7. package/.agents/skills/angular-developer/references/components.md +117 -0
  8. package/.agents/skills/angular-developer/references/creating-services.md +97 -0
  9. package/.agents/skills/angular-developer/references/data-resolvers.md +69 -0
  10. package/.agents/skills/angular-developer/references/define-routes.md +67 -0
  11. package/.agents/skills/angular-developer/references/defining-providers.md +72 -0
  12. package/.agents/skills/angular-developer/references/di-fundamentals.md +116 -0
  13. package/.agents/skills/angular-developer/references/e2e-testing.md +39 -0
  14. package/.agents/skills/angular-developer/references/effects.md +83 -0
  15. package/.agents/skills/angular-developer/references/environment-configuration.md +132 -0
  16. package/.agents/skills/angular-developer/references/hierarchical-injectors.md +43 -0
  17. package/.agents/skills/angular-developer/references/host-elements.md +80 -0
  18. package/.agents/skills/angular-developer/references/injection-context.md +63 -0
  19. package/.agents/skills/angular-developer/references/inputs.md +101 -0
  20. package/.agents/skills/angular-developer/references/linked-signal.md +59 -0
  21. package/.agents/skills/angular-developer/references/loading-strategies.md +61 -0
  22. package/.agents/skills/angular-developer/references/mcp.md +106 -0
  23. package/.agents/skills/angular-developer/references/migrations.md +30 -0
  24. package/.agents/skills/angular-developer/references/navigate-to-routes.md +69 -0
  25. package/.agents/skills/angular-developer/references/outputs.md +86 -0
  26. package/.agents/skills/angular-developer/references/reactive-forms.md +118 -0
  27. package/.agents/skills/angular-developer/references/rendering-strategies.md +44 -0
  28. package/.agents/skills/angular-developer/references/resource.md +74 -0
  29. package/.agents/skills/angular-developer/references/route-animations.md +56 -0
  30. package/.agents/skills/angular-developer/references/route-guards.md +52 -0
  31. package/.agents/skills/angular-developer/references/router-lifecycle.md +45 -0
  32. package/.agents/skills/angular-developer/references/router-testing.md +87 -0
  33. package/.agents/skills/angular-developer/references/show-routes-with-outlets.md +68 -0
  34. package/.agents/skills/angular-developer/references/signal-forms.md +905 -0
  35. package/.agents/skills/angular-developer/references/signals-overview.md +94 -0
  36. package/.agents/skills/angular-developer/references/tailwind-css.md +69 -0
  37. package/.agents/skills/angular-developer/references/template-driven-forms.md +114 -0
  38. package/.agents/skills/angular-developer/references/testing-fundamentals.md +63 -0
  39. package/.editorconfig +17 -0
  40. package/.github/workflows/release.yml +39 -0
  41. package/.husky/commit-msg +1 -0
  42. package/.husky/pre-commit +1 -0
  43. package/.prettierignore +6 -0
  44. package/.prettierrc +17 -0
  45. package/.releaserc.json +41 -0
  46. package/.vscode/extensions.json +4 -0
  47. package/.vscode/launch.json +20 -0
  48. package/.vscode/tasks.json +42 -0
  49. package/CHANGELOG.md +132 -0
  50. package/CONTRIBUTING.md +70 -0
  51. package/README.md +19 -0
  52. package/angular.json +118 -0
  53. package/commitlint.config.js +3 -0
  54. package/package.json +52 -0
  55. package/projects/demo/.postcssrc.json +5 -0
  56. package/projects/demo/public/favicon.ico +0 -0
  57. package/projects/demo/src/app/app.config.server.ts +10 -0
  58. package/projects/demo/src/app/app.config.ts +9 -0
  59. package/projects/demo/src/app/app.css +5 -0
  60. package/projects/demo/src/app/app.html +1 -0
  61. package/projects/demo/src/app/app.routes.server.ts +8 -0
  62. package/projects/demo/src/app/app.routes.ts +28 -0
  63. package/projects/demo/src/app/app.spec.ts +23 -0
  64. package/projects/demo/src/app/app.ts +12 -0
  65. package/projects/demo/src/app/components/about/about.css +0 -0
  66. package/projects/demo/src/app/components/about/about.html +1 -0
  67. package/projects/demo/src/app/components/about/about.ts +9 -0
  68. package/projects/demo/src/app/components/home/home.css +5 -0
  69. package/projects/demo/src/app/components/home/home.html +8 -0
  70. package/projects/demo/src/app/components/home/home.ts +11 -0
  71. package/projects/demo/src/app/components/layout/layout.css +13 -0
  72. package/projects/demo/src/app/components/layout/layout.html +10 -0
  73. package/projects/demo/src/app/components/layout/layout.ts +10 -0
  74. package/projects/demo/src/app/components/samples/samples.css +0 -0
  75. package/projects/demo/src/app/components/samples/samples.html +1 -0
  76. package/projects/demo/src/app/components/samples/samples.ts +9 -0
  77. package/projects/demo/src/app/components/video-horizontal/video-horizontal.css +0 -0
  78. package/projects/demo/src/app/components/video-horizontal/video-horizontal.html +3 -0
  79. package/projects/demo/src/app/components/video-horizontal/video-horizontal.ts +20 -0
  80. package/projects/demo/src/app/components/video-vertical/video-vertical.css +0 -0
  81. package/projects/demo/src/app/components/video-vertical/video-vertical.html +3 -0
  82. package/projects/demo/src/app/components/video-vertical/video-vertical.ts +25 -0
  83. package/projects/demo/src/index.html +13 -0
  84. package/projects/demo/src/main.server.ts +7 -0
  85. package/projects/demo/src/main.ts +5 -0
  86. package/projects/demo/src/server.ts +66 -0
  87. package/projects/demo/src/styles.css +3 -0
  88. package/projects/demo/tsconfig.app.json +10 -0
  89. package/projects/demo/tsconfig.spec.json +10 -0
  90. package/projects/ngx-media/README.md +172 -0
  91. package/projects/ngx-media/ng-package.json +7 -0
  92. package/projects/ngx-media/package.json +31 -0
  93. package/projects/ngx-media/src/lib/models/camera.types.ts +14 -0
  94. package/projects/ngx-media/src/lib/ngx-media.ts +257 -0
  95. package/projects/ngx-media/src/lib/utils/media-capture-error.ts +14 -0
  96. package/projects/ngx-media/src/public-api.ts +7 -0
  97. package/projects/ngx-media/tsconfig.lib.json +13 -0
  98. package/projects/ngx-media/tsconfig.lib.prod.json +11 -0
  99. package/projects/ngx-media/tsconfig.spec.json +10 -0
  100. package/skills-lock.json +11 -0
  101. package/tsconfig.json +40 -0
@@ -0,0 +1,70 @@
1
+ # Contributing
2
+
3
+ ## Setup
4
+
5
+ ```bash
6
+ pnpm install
7
+ ```
8
+
9
+ Husky git hooks are installed automatically.
10
+
11
+ ## Commit Convention
12
+
13
+ This project uses [Conventional Commits](https://www.conventionalcommits.org/).
14
+ Every commit message is validated by **commitlint** via a husky `commit-msg` hook.
15
+
16
+ ### Format
17
+
18
+ ```
19
+ <type>(<scope>): <short description>
20
+ ```
21
+
22
+ ### Common types
23
+
24
+ | Type | When to use | Triggers release? |
25
+ | ---------- | ------------------------------------ | ----------------- |
26
+ | `feat` | A new feature | minor |
27
+ | `fix` | A bug fix | patch |
28
+ | `docs` | Documentation only | no |
29
+ | `style` | Formatting, missing semicolons, etc. | no |
30
+ | `refactor` | Code change that is not feat or fix | no |
31
+ | `perf` | Performance improvement | patch |
32
+ | `test` | Adding or updating tests | no |
33
+ | `chore` | Tooling, dependencies, CI | no |
34
+
35
+ A commit with `BREAKING CHANGE:` in the footer (or `!` after the type) triggers a **major** release.
36
+
37
+ ### Examples
38
+
39
+ ```
40
+ feat(camera): add device switching support
41
+ fix(stream): handle permission denied on Safari
42
+ docs: update README installation steps
43
+ feat!: drop Angular 18 support
44
+ ```
45
+
46
+ ## Building
47
+
48
+ ```bash
49
+ pnpm build:lib # build the library
50
+ pnpm build # build everything (library + demo)
51
+ ```
52
+
53
+ ## Releases
54
+
55
+ Releases are fully automated via **semantic-release** on GitHub Actions.
56
+ Pushing to `main` (or `master`) triggers:
57
+
58
+ 1. Version bump based on commit types
59
+ 2. `CHANGELOG.md` update
60
+ 3. npm publish
61
+ 4. GitHub release with notes
62
+
63
+ No manual version bumps or tags are needed.
64
+
65
+ ### Required repository secrets
66
+
67
+ | Secret | Purpose |
68
+ | -------------- | ---------------------------- |
69
+ | `NPM_TOKEN` | npm publish authentication |
70
+ | `GITHUB_TOKEN` | Provided automatically by CI |
package/README.md ADDED
@@ -0,0 +1,19 @@
1
+ # What it is
2
+
3
+ _Angular library for easier camera/media access in web apps._
4
+
5
+ ---
6
+
7
+ # Planned features
8
+
9
+ - Auto Destroy and clearance on component destroy
10
+ - Easy to use ML features
11
+ - Easy to use component
12
+
13
+ ---
14
+
15
+ # Installation
16
+
17
+ ```bash
18
+ npm install ngx-media
19
+ ```
package/angular.json ADDED
@@ -0,0 +1,118 @@
1
+ {
2
+ "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
3
+ "version": 1,
4
+ "cli": {
5
+ "packageManager": "pnpm"
6
+ },
7
+ "newProjectRoot": "projects",
8
+ "projects": {
9
+ "ngx-media": {
10
+ "projectType": "library",
11
+ "root": "projects/ngx-media",
12
+ "sourceRoot": "projects/ngx-media/src",
13
+ "prefix": "lib",
14
+ "schematics": {
15
+ "@schematics/angular:service": {
16
+ "skipTests": true,
17
+ "addTypeToClassName": true,
18
+ "type": "service",
19
+ "path": "projects/ngx-media/src/lib/services"
20
+ }
21
+ },
22
+ "architect": {
23
+ "build": {
24
+ "builder": "@angular/build:ng-packagr",
25
+ "configurations": {
26
+ "production": {
27
+ "tsConfig": "projects/ngx-media/tsconfig.lib.prod.json"
28
+ },
29
+ "development": {
30
+ "tsConfig": "projects/ngx-media/tsconfig.lib.json"
31
+ }
32
+ },
33
+ "defaultConfiguration": "production"
34
+ },
35
+ "test": {
36
+ "builder": "@angular/build:unit-test",
37
+ "options": {
38
+ "tsConfig": "projects/ngx-media/tsconfig.spec.json"
39
+ }
40
+ }
41
+ }
42
+ },
43
+ "demo": {
44
+ "projectType": "application",
45
+ "schematics": {
46
+ "@schematics/angular:component": {
47
+ "skipTests": true,
48
+ "path": "projects/demo/src/app/components"
49
+ }
50
+ },
51
+ "root": "projects/demo",
52
+ "sourceRoot": "projects/demo/src",
53
+ "prefix": "app",
54
+ "architect": {
55
+ "build": {
56
+ "builder": "@angular/build:application",
57
+ "options": {
58
+ "browser": "projects/demo/src/main.ts",
59
+ "tsConfig": "projects/demo/tsconfig.app.json",
60
+ "assets": [
61
+ {
62
+ "glob": "**/*",
63
+ "input": "projects/demo/public"
64
+ }
65
+ ],
66
+ "styles": ["projects/demo/src/styles.css"],
67
+ "server": "projects/demo/src/main.server.ts",
68
+ "outputMode": "server",
69
+ "security": {
70
+ "allowedHosts": []
71
+ },
72
+ "ssr": {
73
+ "entry": "projects/demo/src/server.ts"
74
+ }
75
+ },
76
+ "configurations": {
77
+ "production": {
78
+ "budgets": [
79
+ {
80
+ "type": "initial",
81
+ "maximumWarning": "500kB",
82
+ "maximumError": "1MB"
83
+ },
84
+ {
85
+ "type": "anyComponentStyle",
86
+ "maximumWarning": "4kB",
87
+ "maximumError": "8kB"
88
+ }
89
+ ],
90
+ "outputHashing": "all"
91
+ },
92
+ "development": {
93
+ "optimization": false,
94
+ "extractLicenses": false,
95
+ "sourceMap": true
96
+ }
97
+ },
98
+ "defaultConfiguration": "production"
99
+ },
100
+ "serve": {
101
+ "builder": "@angular/build:dev-server",
102
+ "configurations": {
103
+ "production": {
104
+ "buildTarget": "demo:build:production"
105
+ },
106
+ "development": {
107
+ "buildTarget": "demo:build:development"
108
+ }
109
+ },
110
+ "defaultConfiguration": "development"
111
+ },
112
+ "test": {
113
+ "builder": "@angular/build:unit-test"
114
+ }
115
+ }
116
+ }
117
+ }
118
+ }
@@ -0,0 +1,3 @@
1
+ module.exports = {
2
+ extends: ['@commitlint/config-conventional'],
3
+ };
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "ngx-media",
3
+ "version": "1.0.0",
4
+ "scripts": {
5
+ "ng": "ng",
6
+ "start": "ng serve --project=demo",
7
+ "build": "ng build",
8
+ "build:lib": "ng build ngx-media --configuration production",
9
+ "watch": "ng build --watch --configuration development",
10
+ "test": "ng test",
11
+ "semantic-release": "semantic-release",
12
+ "serve:ssr:demo": "node dist/demo/server/server.mjs",
13
+ "prepare": "husky"
14
+ },
15
+ "private": false,
16
+ "packageManager": "pnpm@11.5.2",
17
+ "dependencies": {
18
+ "@angular/common": "^22.0.0",
19
+ "@angular/compiler": "^22.0.0",
20
+ "@angular/core": "^22.0.0",
21
+ "@angular/forms": "^22.0.0",
22
+ "@angular/platform-browser": "^22.0.0",
23
+ "@angular/platform-server": "^22.0.0",
24
+ "@angular/router": "^22.0.0",
25
+ "@angular/ssr": "^22.0.5",
26
+ "express": "^5.1.0",
27
+ "rxjs": "~7.8.0",
28
+ "tslib": "^2.3.0"
29
+ },
30
+ "devDependencies": {
31
+ "@angular/build": "^22.0.5",
32
+ "@angular/cli": "^22.0.5",
33
+ "@angular/compiler-cli": "^22.0.0",
34
+ "@commitlint/cli": "^21.2.0",
35
+ "@commitlint/config-conventional": "^21.2.0",
36
+ "@semantic-release/changelog": "^6.0.3",
37
+ "@semantic-release/git": "^10.0.1",
38
+ "@tailwindcss/postcss": "^4.1.12",
39
+ "@types/express": "^5.0.1",
40
+ "@types/node": "^20.17.19",
41
+ "husky": "^9.1.7",
42
+ "jsdom": "^28.0.0",
43
+ "ng-packagr": "^22.0.0",
44
+ "postcss": "^8.5.3",
45
+ "prettier": "^3.8.1",
46
+ "rxjs-watcher": "^1.2.2",
47
+ "semantic-release": "^25.0.5",
48
+ "tailwindcss": "^4.1.12",
49
+ "typescript": "~6.0.2",
50
+ "vitest": "^4.0.8"
51
+ }
52
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "plugins": {
3
+ "@tailwindcss/postcss": {}
4
+ }
5
+ }
Binary file
@@ -0,0 +1,10 @@
1
+ import { mergeApplicationConfig, ApplicationConfig } from '@angular/core';
2
+ import { provideServerRendering, withRoutes } from '@angular/ssr';
3
+ import { appConfig } from './app.config';
4
+ import { serverRoutes } from './app.routes.server';
5
+
6
+ const serverConfig: ApplicationConfig = {
7
+ providers: [provideServerRendering(withRoutes(serverRoutes))],
8
+ };
9
+
10
+ export const config = mergeApplicationConfig(appConfig, serverConfig);
@@ -0,0 +1,9 @@
1
+ import { ApplicationConfig, provideBrowserGlobalErrorListeners } from '@angular/core';
2
+ import { provideRouter } from '@angular/router';
3
+
4
+ import { routes } from './app.routes';
5
+ import { provideClientHydration } from '@angular/platform-browser';
6
+
7
+ export const appConfig: ApplicationConfig = {
8
+ providers: [provideBrowserGlobalErrorListeners(), provideRouter(routes), provideClientHydration()],
9
+ };
@@ -0,0 +1,5 @@
1
+ @reference "tailwindcss";
2
+
3
+ :host {
4
+ @apply flex flex-col justify-center items-center min-h-screen;
5
+ }
@@ -0,0 +1 @@
1
+ <router-outlet />
@@ -0,0 +1,8 @@
1
+ import { RenderMode, ServerRoute } from '@angular/ssr';
2
+
3
+ export const serverRoutes: ServerRoute[] = [
4
+ {
5
+ path: '**',
6
+ renderMode: RenderMode.Client,
7
+ },
8
+ ];
@@ -0,0 +1,28 @@
1
+ import { Routes } from '@angular/router';
2
+ import { Layout } from './components/layout/layout';
3
+
4
+ export const routes: Routes = [
5
+ {
6
+ path: '',
7
+ component: Layout,
8
+ children: [
9
+ {
10
+ path: '',
11
+ loadComponent: () => import('./components/home/home').then((c) => c.Home),
12
+ },
13
+ {
14
+ path: 'about',
15
+ loadComponent: () => import('./components/about/about').then((c) => c.About),
16
+ },
17
+ {
18
+ path: 'samples',
19
+ loadComponent: () => import('./components/samples/samples').then((c) => c.Samples),
20
+ },
21
+ {
22
+ path: '**',
23
+ redirectTo: '',
24
+ pathMatch: 'full',
25
+ },
26
+ ],
27
+ },
28
+ ];
@@ -0,0 +1,23 @@
1
+ import { TestBed } from '@angular/core/testing';
2
+ import { App } from './app';
3
+
4
+ describe('App', () => {
5
+ beforeEach(async () => {
6
+ await TestBed.configureTestingModule({
7
+ imports: [App],
8
+ }).compileComponents();
9
+ });
10
+
11
+ it('should create the app', () => {
12
+ const fixture = TestBed.createComponent(App);
13
+ const app = fixture.componentInstance;
14
+ expect(app).toBeTruthy();
15
+ });
16
+
17
+ it('should render title', async () => {
18
+ const fixture = TestBed.createComponent(App);
19
+ await fixture.whenStable();
20
+ const compiled = fixture.nativeElement as HTMLElement;
21
+ expect(compiled.querySelector('h1')?.textContent).toContain('Hello, demo');
22
+ });
23
+ });
@@ -0,0 +1,12 @@
1
+ import { Component, signal } from '@angular/core';
2
+ import { RouterOutlet } from '@angular/router';
3
+
4
+ @Component({
5
+ selector: 'app-root',
6
+ imports: [RouterOutlet],
7
+ templateUrl: './app.html',
8
+ styleUrl: './app.css',
9
+ })
10
+ export class App {
11
+ protected readonly title = signal('demo');
12
+ }
@@ -0,0 +1 @@
1
+ <p>about works!</p>
@@ -0,0 +1,9 @@
1
+ import { Component } from '@angular/core';
2
+
3
+ @Component({
4
+ selector: 'app-about',
5
+ imports: [],
6
+ templateUrl: './about.html',
7
+ styleUrl: './about.css',
8
+ })
9
+ export class About {}
@@ -0,0 +1,5 @@
1
+ @reference "tailwindcss";
2
+
3
+ .video-container {
4
+ @apply flex flex-row gap-4 wrap-normal;
5
+ }
@@ -0,0 +1,8 @@
1
+ <h1>Home</h1>
2
+ <p>It works!</p>
3
+ <hr />
4
+
5
+ <div class="video-container">
6
+ <app-video-horizontal />
7
+ <app-video-vertical />
8
+ </div>
@@ -0,0 +1,11 @@
1
+ import { Component } from '@angular/core';
2
+ import { VideoHorizontal } from '../video-horizontal/video-horizontal';
3
+ import { VideoVertical } from '../video-vertical/video-vertical';
4
+
5
+ @Component({
6
+ selector: 'app-home',
7
+ imports: [VideoHorizontal, VideoVertical],
8
+ templateUrl: './home.html',
9
+ styleUrl: './home.css',
10
+ })
11
+ export class Home {}
@@ -0,0 +1,13 @@
1
+ @reference "tailwindcss";
2
+
3
+ :host {
4
+ @apply flex flex-row max-w-7xl w-full border-2;
5
+ }
6
+
7
+ aside {
8
+ @apply max-w-60 min-w-45 p-4 bg-amber-200;
9
+ }
10
+
11
+ main {
12
+ @apply grow p-4;
13
+ }
@@ -0,0 +1,10 @@
1
+ <aside>
2
+ <ul>
3
+ <li><a routerLink="/">Home</a></li>
4
+ <li><a routerLink="/about">About</a></li>
5
+ <li><a routerLink="/samples">Samples</a></li>
6
+ </ul>
7
+ </aside>
8
+ <main>
9
+ <router-outlet />
10
+ </main>
@@ -0,0 +1,10 @@
1
+ import { Component } from '@angular/core';
2
+ import { RouterLink, RouterOutlet } from '@angular/router';
3
+
4
+ @Component({
5
+ selector: 'app-layout',
6
+ imports: [RouterOutlet, RouterLink],
7
+ templateUrl: './layout.html',
8
+ styleUrl: './layout.css',
9
+ })
10
+ export class Layout {}
@@ -0,0 +1 @@
1
+ <p>samples works!</p>
@@ -0,0 +1,9 @@
1
+ import { Component } from '@angular/core';
2
+
3
+ @Component({
4
+ selector: 'app-samples',
5
+ imports: [],
6
+ templateUrl: './samples.html',
7
+ styleUrl: './samples.css',
8
+ })
9
+ export class Samples {}
@@ -0,0 +1,3 @@
1
+ <p>video-horizontal works!</p>
2
+
3
+ <video #video width="300" height="400" autoplay [srcObject]="stream()"></video>
@@ -0,0 +1,20 @@
1
+ import { Component, DestroyRef, inject } from '@angular/core';
2
+ import { NgxMedia } from '../../../../../ngx-media/src/lib/ngx-media';
3
+
4
+ @Component({
5
+ selector: 'app-video-horizontal',
6
+ imports: [],
7
+ templateUrl: './video-horizontal.html',
8
+ styleUrl: './video-horizontal.css',
9
+ })
10
+ export class VideoHorizontal {
11
+ private readonly cameraService = new NgxMedia(inject(DestroyRef));
12
+
13
+ protected readonly stream = this.cameraService.stream;
14
+
15
+ constructor() {
16
+ this.cameraService.startStream({
17
+ video: { facingMode: 'user', aspectRatio: 1, width: { exact: 400 }, height: { exact: 300 }, frameRate: 30 },
18
+ });
19
+ }
20
+ }
@@ -0,0 +1,3 @@
1
+ <p>video-vertical works!</p>
2
+
3
+ <video #video width="300" height="400" autoplay [srcObject]="stream$ | async"></video>
@@ -0,0 +1,25 @@
1
+ import { Component, OnDestroy } from '@angular/core';
2
+ import { NgxMedia } from '../../../../../ngx-media/src/lib/ngx-media';
3
+ import { AsyncPipe } from '@angular/common';
4
+
5
+ @Component({
6
+ selector: 'app-video-vertical',
7
+ imports: [AsyncPipe],
8
+ templateUrl: './video-vertical.html',
9
+ styleUrl: './video-vertical.css',
10
+ })
11
+ export class VideoVertical implements OnDestroy {
12
+ private readonly ngxMedia = new NgxMedia();
13
+
14
+ protected readonly stream$ = this.ngxMedia.stream$;
15
+
16
+ constructor() {
17
+ this.ngxMedia.startStream({
18
+ video: { facingMode: 'user', aspectRatio: 1, width: { exact: 300 }, height: { exact: 400 }, frameRate: 30 },
19
+ });
20
+ }
21
+
22
+ ngOnDestroy() {
23
+ this.ngxMedia.destroy();
24
+ }
25
+ }
@@ -0,0 +1,13 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <title>Demo</title>
6
+ <base href="/" />
7
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
8
+ <link rel="icon" type="image/x-icon" href="favicon.ico" />
9
+ </head>
10
+ <body>
11
+ <app-root></app-root>
12
+ </body>
13
+ </html>
@@ -0,0 +1,7 @@
1
+ import { BootstrapContext, bootstrapApplication } from '@angular/platform-browser';
2
+ import { App } from './app/app';
3
+ import { config } from './app/app.config.server';
4
+
5
+ const bootstrap = (context: BootstrapContext) => bootstrapApplication(App, config, context);
6
+
7
+ export default bootstrap;
@@ -0,0 +1,5 @@
1
+ import { bootstrapApplication } from '@angular/platform-browser';
2
+ import { appConfig } from './app/app.config';
3
+ import { App } from './app/app';
4
+
5
+ bootstrapApplication(App, appConfig).catch((err) => console.error(err));
@@ -0,0 +1,66 @@
1
+ import {
2
+ AngularNodeAppEngine,
3
+ createNodeRequestHandler,
4
+ isMainModule,
5
+ writeResponseToNodeResponse,
6
+ } from '@angular/ssr/node';
7
+ import express from 'express';
8
+ import { join } from 'node:path';
9
+
10
+ const browserDistFolder = join(import.meta.dirname, '../browser');
11
+
12
+ const app = express();
13
+ const angularApp = new AngularNodeAppEngine();
14
+
15
+ /**
16
+ * Example Express Rest API endpoints can be defined here.
17
+ * Uncomment and define endpoints as necessary.
18
+ *
19
+ * Example:
20
+ * ```ts
21
+ * app.get('/api/{*splat}', (req, res) => {
22
+ * // Handle API request
23
+ * });
24
+ * ```
25
+ */
26
+
27
+ /**
28
+ * Serve static files from /browser
29
+ */
30
+ app.use(
31
+ express.static(browserDistFolder, {
32
+ maxAge: '1y',
33
+ index: false,
34
+ redirect: false,
35
+ }),
36
+ );
37
+
38
+ /**
39
+ * Handle all other requests by rendering the Angular application.
40
+ */
41
+ app.use((req, res, next) => {
42
+ angularApp
43
+ .handle(req)
44
+ .then((response) => (response ? writeResponseToNodeResponse(response, res) : next()))
45
+ .catch(next);
46
+ });
47
+
48
+ /**
49
+ * Start the server if this module is the main entry point, or it is ran via PM2.
50
+ * The server listens on the port defined by the `PORT` environment variable, or defaults to 4000.
51
+ */
52
+ if (isMainModule(import.meta.url) || process.env['pm_id']) {
53
+ const port = process.env['PORT'] || 4000;
54
+ app.listen(port, (error) => {
55
+ if (error) {
56
+ throw error;
57
+ }
58
+
59
+ console.log(`Node Express server listening on http://localhost:${port}`);
60
+ });
61
+ }
62
+
63
+ /**
64
+ * Request handler used by the Angular CLI (for dev-server and during build) or Firebase Cloud Functions.
65
+ */
66
+ export const reqHandler = createNodeRequestHandler(app);
@@ -0,0 +1,3 @@
1
+ /* You can add global styles to this file, and also import other style files */
2
+
3
+ @import 'tailwindcss';
@@ -0,0 +1,10 @@
1
+ /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
2
+ /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
3
+ {
4
+ "extends": "../../tsconfig.json",
5
+ "compilerOptions": {
6
+ "types": ["node"]
7
+ },
8
+ "include": ["src/**/*.ts"],
9
+ "exclude": ["src/**/*.spec.ts"]
10
+ }