prismcast 0.0.1 → 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 (70) hide show
  1. package/.github/ISSUE_TEMPLATE/config.yml +3 -0
  2. package/.github/ISSUE_TEMPLATE/feature-request.yml +29 -0
  3. package/.github/ISSUE_TEMPLATE/support-request.yml +89 -0
  4. package/.github/workflows/ci.yml +84 -0
  5. package/.github/workflows/issue-stale.yml +27 -0
  6. package/.github/workflows/lock-threads.yml +28 -0
  7. package/LICENSE.md +7 -0
  8. package/README.md +153 -3
  9. package/eslint.config.mjs +71 -0
  10. package/package.json +48 -6
  11. package/prismcast.png +0 -0
  12. package/prismcast.svg +74 -0
  13. package/src/app.ts +409 -0
  14. package/src/browser/cdp.ts +207 -0
  15. package/src/browser/channelSelection.ts +246 -0
  16. package/src/browser/display.ts +73 -0
  17. package/src/browser/index.ts +1254 -0
  18. package/src/browser/video.ts +1107 -0
  19. package/src/channels/index.ts +220 -0
  20. package/src/config/index.ts +297 -0
  21. package/src/config/presets.ts +390 -0
  22. package/src/config/profiles.ts +574 -0
  23. package/src/config/userChannels.ts +557 -0
  24. package/src/config/userConfig.ts +1310 -0
  25. package/src/index.ts +174 -0
  26. package/src/routes/assets.ts +109 -0
  27. package/src/routes/auth.ts +144 -0
  28. package/src/routes/components.ts +428 -0
  29. package/src/routes/config.ts +1711 -0
  30. package/src/routes/health.ts +99 -0
  31. package/src/routes/hls.ts +34 -0
  32. package/src/routes/index.ts +48 -0
  33. package/src/routes/logs.ts +244 -0
  34. package/src/routes/playlist.ts +105 -0
  35. package/src/routes/root.ts +1903 -0
  36. package/src/routes/streams.ts +146 -0
  37. package/src/routes/theme.ts +310 -0
  38. package/src/routes/ui.ts +427 -0
  39. package/src/service/commands.ts +576 -0
  40. package/src/service/generators.ts +652 -0
  41. package/src/service/index.ts +6 -0
  42. package/src/streaming/fmp4Segmenter.ts +354 -0
  43. package/src/streaming/hls.ts +599 -0
  44. package/src/streaming/hlsSegments.ts +182 -0
  45. package/src/streaming/lifecycle.ts +199 -0
  46. package/src/streaming/monitor.ts +1489 -0
  47. package/src/streaming/mp4Parser.ts +178 -0
  48. package/src/streaming/registry.ts +276 -0
  49. package/src/streaming/setup.ts +695 -0
  50. package/src/streaming/showInfo.ts +546 -0
  51. package/src/streaming/statusEmitter.ts +258 -0
  52. package/src/types/global.d.ts +18 -0
  53. package/src/types/index.ts +724 -0
  54. package/src/utils/delay.ts +17 -0
  55. package/src/utils/errors.ts +48 -0
  56. package/src/utils/evaluate.ts +175 -0
  57. package/src/utils/ffmpeg.ts +278 -0
  58. package/src/utils/fileLogger.ts +366 -0
  59. package/src/utils/format.ts +32 -0
  60. package/src/utils/html.ts +32 -0
  61. package/src/utils/index.ts +16 -0
  62. package/src/utils/logEmitter.ts +55 -0
  63. package/src/utils/logger.ts +268 -0
  64. package/src/utils/morganStream.ts +48 -0
  65. package/src/utils/platform.ts +230 -0
  66. package/src/utils/retry.ts +118 -0
  67. package/src/utils/streamContext.ts +68 -0
  68. package/tsconfig.json +11 -0
  69. package/LICENSE +0 -16
  70. package/index.js +0 -6
@@ -0,0 +1,3 @@
1
+ # Issue creation settings.
2
+ #
3
+ blank_issues_enabled: false
@@ -0,0 +1,29 @@
1
+ name: Feature Request
2
+ description: Suggest an idea for an enhancement to PrismCast. Please read the PrismCast documentation first to verify what you're looking for isn't already implemented.
3
+ labels: enhancement
4
+ body:
5
+ - type: markdown
6
+ attributes:
7
+ value: |
8
+ ### Before opening a feature request, please ensure you have read the [documentation](https://github.com/hjdhjd/prismcast#readme) to see if the feature you're looking for doesn't already exist.
9
+ - type: textarea
10
+ id: feature-request
11
+ attributes:
12
+ label: Describe the feature request
13
+ description: Please describe the feature you are requesting. If the feature request relates to a specific problem you are encountering, please describe the use case.
14
+ validations:
15
+ required: true
16
+ - type: textarea
17
+ id: proposed-solution
18
+ attributes:
19
+ label: Describe the proposed solution
20
+ description: Please describe the proposed solution to the problem or use case described above.
21
+ validations:
22
+ required: true
23
+ - type: textarea
24
+ id: alternatives
25
+ attributes:
26
+ label: Describe alternatives you have considered
27
+ description: Please describe alternative approaches you've explored or considered to address the requested feature.
28
+ validations:
29
+ required: true
@@ -0,0 +1,89 @@
1
+ name: Support Request
2
+ description: Report a bug or request help. Please read the PrismCast documentation before creating a support request.
3
+ body:
4
+ - type: markdown
5
+ attributes:
6
+ value: |
7
+ ### Before opening a support request, please ensure you have read the [documentation](https://github.com/hjdhjd/prismcast#readme). ***Questions and topics already addressed in the documentation, or in prior issue reports, will be closed without a response.***
8
+
9
+ - type: input
10
+ id: prismcast-version
11
+ attributes:
12
+ label: PrismCast Version
13
+ description: Which version of PrismCast are you running? (Run `prismcast --version` to check)
14
+ placeholder: e.g. v1.0.0
15
+ validations:
16
+ required: true
17
+
18
+ - type: input
19
+ id: platform-os
20
+ attributes:
21
+ label: Platform and OS
22
+ description: What hardware and operating system are you running PrismCast on?
23
+ placeholder: e.g. macOS Sequoia 15.2, Ubuntu 24.04, Windows 11
24
+ validations:
25
+ required: true
26
+
27
+ - type: input
28
+ id: node
29
+ attributes:
30
+ label: Node Version
31
+ description: Which version of Node are you running? (Run `node --version` to check)
32
+ placeholder: e.g. v22.0.0
33
+ validations:
34
+ required: true
35
+
36
+ - type: input
37
+ id: chrome
38
+ attributes:
39
+ label: Chrome Version
40
+ description: Which version of Google Chrome are you using? (Check chrome://version or About Google Chrome)
41
+ placeholder: e.g. 131.0.6778.86
42
+ validations:
43
+ required: true
44
+
45
+ - type: input
46
+ id: channel
47
+ attributes:
48
+ label: Affected Channel (if applicable)
49
+ description: If this issue relates to a specific channel, which one?
50
+ placeholder: e.g. NBC, CNN, or a custom channel URL
51
+ validations:
52
+ required: false
53
+
54
+ - type: textarea
55
+ id: what-happened
56
+ attributes:
57
+ label: Describe the problem
58
+ description: Please describe the issue you're encountering, including steps to reproduce.
59
+ validations:
60
+ required: true
61
+
62
+ - type: textarea
63
+ id: config
64
+ attributes:
65
+ label: PrismCast Configuration
66
+ description: Please copy and paste your PrismCast configuration from `~/.prismcast/config.json`. Ensure that you redact any sensitive information. This will be automatically formatted into code, so no need for backticks.
67
+ placeholder: Paste your config.json contents here. If you haven't customized any settings, you can write "Default configuration" instead.
68
+ render: json
69
+ validations:
70
+ required: true
71
+
72
+ - type: textarea
73
+ id: logs
74
+ attributes:
75
+ label: PrismCast Log Output
76
+ description: Please copy and paste relevant log output from PrismCast. Include startup logs and any error messages. You can view logs in the web UI at `http://localhost:5589/#logs` or in `~/.prismcast/prismcast.log`. This will be automatically formatted into code, so no need for backticks.
77
+ placeholder: Paste relevant log entries here. Include the full startup sequence if possible.
78
+ render: shell
79
+ validations:
80
+ required: true
81
+
82
+ - type: checkboxes
83
+ id: acknowledgment
84
+ attributes:
85
+ label: Acknowledgment
86
+ description: By submitting this issue, you acknowledge the following.
87
+ options:
88
+ - label: I have read the documentation and searched existing issues before creating this support request.
89
+ required: true
@@ -0,0 +1,84 @@
1
+ # Continuous integration - validate builds when commits are made, and publish when releases are created.
2
+ #
3
+ name: "Continuous Integration"
4
+
5
+ # Run the build on all push, pull request, and release creation events.
6
+ on:
7
+ pull_request:
8
+ push:
9
+ release:
10
+ types: [ published ]
11
+ workflow_dispatch:
12
+
13
+ # OIDC-related permissions for trusted publishing to NPMJS.
14
+ permissions:
15
+ contents: read
16
+ id-token: write
17
+
18
+ jobs:
19
+
20
+ # Run a validation build on LTS versions of node.
21
+ build:
22
+ name: 'Build package'
23
+
24
+ # Create the build matrix for all the environments we're validating against.
25
+ strategy:
26
+ matrix:
27
+ node-version: [ lts/-1, lts/* ]
28
+ os: [ ubuntu-latest ]
29
+
30
+ # Specify the environments we're going to build in.
31
+ runs-on: ${{ matrix.os }}
32
+
33
+ # Execute the build activities.
34
+ steps:
35
+ - name: Checkout the repository.
36
+ uses: actions/checkout@v4
37
+
38
+ - name: Setup the node ${{ matrix.node-version }} environment.
39
+ uses: actions/setup-node@v4
40
+ with:
41
+ node-version: ${{ matrix.node-version }}
42
+
43
+ - name: Build and install the package with a clean slate.
44
+ env:
45
+ CI: true
46
+ ESLINT_MAX_WARNINGS: 0
47
+ run: |
48
+ npm ci
49
+ npm run prepublishOnly
50
+
51
+ # Publish the release to the NPM registry.
52
+ publish-npm:
53
+ name: 'Publish package'
54
+ needs: build
55
+
56
+ # Publish only if we've received a release event and the tag starts with "v" (aka v1.2.3).
57
+ if: github.event_name == 'release' && startsWith(github.ref, 'refs/tags/v')
58
+
59
+ # Specify the environment we're going to build in.
60
+ runs-on: ubuntu-latest
61
+
62
+ # Execute the build and publish activities.
63
+ steps:
64
+ - name: Checkout the repository.
65
+ uses: actions/checkout@v4
66
+
67
+ - name: Setup the node environment.
68
+ uses: actions/setup-node@v4
69
+ with:
70
+
71
+ # Use the oldest node LTS version that we support.
72
+ node-version: lts/-1
73
+
74
+ # Use the NPM registry.
75
+ registry-url: 'https://registry.npmjs.org/'
76
+
77
+ - name: Update npm (required for trusted publishing).
78
+ run: npm install -g npm@latest
79
+
80
+ - name: Install the package with a clean slate.
81
+ run: npm ci
82
+
83
+ - name: Publish the package to NPM.
84
+ run: npm publish --access public --provenance
@@ -0,0 +1,27 @@
1
+ # Close stale issues after a defined period of time.
2
+ #
3
+ name: Close Stale Issues
4
+
5
+ on:
6
+ issues:
7
+ types: [reopened]
8
+ schedule:
9
+ - cron: "0 * * * *"
10
+
11
+ jobs:
12
+ stale:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - name: Autoclose stale issues.
16
+ uses: actions/stale@v9
17
+ with:
18
+ days-before-close: 2
19
+ days-before-stale: 4
20
+ exempt-issue-labels: 'discussion,help wanted,long running'
21
+ exempt-pr-labels: 'awaiting-approval,work-in-progress'
22
+ remove-stale-when-updated: true
23
+ repo-token: ${{ secrets.GITHUB_TOKEN }}
24
+ stale-issue-label: 'stale'
25
+ stale-issue-message: 'This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.'
26
+ stale-pr-label: 'stale'
27
+ stale-pr-message: 'This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.'
@@ -0,0 +1,28 @@
1
+ name: 'Lock Threads'
2
+
3
+ on:
4
+ schedule:
5
+ - cron: '30 0/6 * * *'
6
+ workflow_dispatch:
7
+
8
+ permissions:
9
+ issues: write
10
+ pull-requests: write
11
+
12
+ concurrency:
13
+ group: lock
14
+
15
+ jobs:
16
+ action:
17
+ runs-on: ubuntu-latest
18
+ steps:
19
+ - uses: dessant/lock-threads@v5
20
+ with:
21
+ github-token: ${{ secrets.GITHUB_TOKEN }}
22
+ issue-inactive-days: "2"
23
+ exclude-any-issue-labels: "discussion"
24
+ issue-comment: "This issue is locked to prevent necroposting on closed issues. Please create a new issue for related support requests, bug reports, or feature suggestions."
25
+ issue-lock-reason: ""
26
+ pr-inactive-days: "7"
27
+ pr-comment: "This issue is locked to prevent necroposting on closed issues. Please create a new issue for related discussion, if needed."
28
+ pr-lock-reason: ""
package/LICENSE.md ADDED
@@ -0,0 +1,7 @@
1
+ # ISC License
2
+
3
+ Copyright (c) 2024-2026 HJD (https://github.com/hjdhjd)
4
+
5
+ Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
package/README.md CHANGED
@@ -1,5 +1,155 @@
1
- # my-package
1
+ <SPAN ALIGN="CENTER" STYLE="text-align:center">
2
+ <DIV ALIGN="CENTER" STYLE="text-align:center">
2
3
 
3
- **Placeholder.**
4
+ [![PrismCast: Browser-based live TV capture for Channels DVR](https://raw.githubusercontent.com/hjdhjd/prismcast/main/prismcast.svg)](https://github.com/hjdhjd/prismcast)
4
5
 
5
- If you installed this by accident, uninstall it.
6
+ # PrismCast
7
+
8
+ [![Downloads](https://img.shields.io/npm/dt/prismcast?color=636382&logo=icloud&logoColor=%23FFFFFF&style=for-the-badge)](https://www.npmjs.com/package/prismcast)
9
+ [![Version](https://img.shields.io/npm/v/prismcast?color=636382&label=PrismCast&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pgo8IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDIwMDEwOTA0Ly9FTiIKICJodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAxL1JFQy1TVkctMjAwMTA5MDQvRFREL3N2ZzEwLmR0ZCI+CjxzdmcgdmVyc2lvbj0iMS4wIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiB3aWR0aD0iMTAwMCIgaGVpZ2h0PSIxMDAwIiB2aWV3Qm94PSIwIDAgMTAwMC4wMDAwMDAgMTAwMC4wMDAwMDAiCiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWlkWU1pZCBtZWV0Ij4KPG1ldGFkYXRhPgpDcmVhdGVkIGJ5IHBvdHJhY2UgMS4xNiwgd3JpdHRlbiBieSBQZXRlciBTZWxpbmdlciAyMDAxLTIwMTkKPC9tZXRhZGF0YT4KPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMC4wMDAwMDAsMTAwMC4wMDAwMDApIHNjYWxlKDAuMTAwMDAwLC0wLjEwMDAwMCkiCmZpbGw9IiNGRkZGRkYiIHN0cm9rZT0ibm9uZSI+CjxwYXRoIGQ9Ik0zODYwIDc3OTYgYy0xNzkgLTUzIC0yMjEgLTEwMiAtNDYwIC01NDEgLTE4IC0zMyAtNjggLTEyMSAtMTEwCi0xOTUgLTQyIC03NCAtMTIxIC0yMTYgLTE3NSAtMzE1IC01NCAtOTkgLTExMiAtMjA1IC0xMzAgLTIzNSAtMTggLTMwIC00OQotODQgLTY3IC0xMjAgLTQwIC03NiAtMTI0IC0yMjcgLTE3OCAtMzIwIC01MyAtOTEgLTcwIC0xMjIgLTE3OCAtMzIwIC01MiAtOTYKLTk4IC0xNzkgLTEwMiAtMTg1IC00IC01IC0yOSAtNTAgLTU1IC0xMDAgLTI2IC00OSAtNzYgLTEzOSAtMTEwIC0yMDAgLTM0Ci02MCAtMTAwIC0xODAgLTE0NSAtMjY1IC00NiAtODUgLTg2IC0xNTkgLTkwIC0xNjUgLTUgLTUgLTI2IC00NSAtNDkgLTg4IC02OAotMTMwIC0xMjIgLTIyNyAtMTc3IC0zMjIgLTI4IC00OSAtOTggLTE3NSAtMTU0IC0yODAgLTEwMyAtMTkxIC0xMTkgLTIyMAotMjA0IC0zNzQgLTI1IC00NiAtNDYgLTg2IC00NiAtODggMCAtMyAtOCAtMTcgLTE5IC0zMSAtMTAgLTE1IC00NCAtNzYgLTc2Ci0xMzcgLTg1IC0xNjEgLTExMSAtMjA4IC0xODQgLTMzMCAtMzYgLTYwIC03NCAtMTMwIC04NSAtMTU1IC0xMCAtMjUgLTIxIC01MgotMjUgLTYwIC00NCAtODkgLTQ0IC0yODYgLTEgLTM2OSA0IC05IDIxIC00MyAzNiAtNzYgNjQgLTEzNiAyNDYgLTI3MSA0MTQKLTMwNiA5OCAtMjEgNTMxOCAtMjEgNTQwMCAwIDM5MyA5OSA1MzEgNDY3IDMyMyA4NjEgLTg3IDE2NCAtMzA0IDU1MSAtMzIzCjU3NSAtNCA2IC0xOCAzMCAtMzIgNTUgLTI0MyA0NDAgLTI2MyA0NzEgLTMzMCA1MDQgLTQ3IDIzIC05NCAzNCAtMzEzIDc2IC0yNwo1IC0xMDQgMTYgLTE3MCAyNSAtNjYgOSAtMTc4IDI2IC0yNTAgMzcgLTEzOCAyMSAtMTk5IDMwIC0zNjAgNTMgLTU1IDggLTEyOQoxOSAtMTY1IDI0IC0zNiA1IC0xMDEgMTQgLTE0NSAyMCAtNDQgNiAtMTA3IDE1IC0xNDAgMjEgLTMzIDUgLTk2IDE0IC0xNDAgMTkKLTQ0IDYgLTEzNiAxOCAtMjA0IDI3IC0zNzAgNDkgLTQ4MSAtMTAyIC0xNTEgLTIwNSA1OCAtMTggMTE2IC0zNyAxMzAgLTQyIDE0Ci00IDYxIC0xNyAxMDUgLTI4IDcyIC0xOCAxNTMgLTQwIDMyNSAtODcgMjQyIC02NyAyNDMgLTY3IDQxMCAtOTggNDcgLTkgMTAzCi0yMCAxMjUgLTI1IDIyIC01IDc2IC0xNyAxMjAgLTI2IDIyOCAtNDggNTIzIC0xMjAgNTY3IC0xMzcgMzEgLTExIDQwIC0yNAoxMDcgLTE0NiA3OSAtMTQyIDMwNiAtNTM0IDMzMyAtNTc0IDE2OSAtMjQ4IDIwNiAtNDM3IDk2IC00OTQgLTU0IC0yOCAtMjc4NwotNDggLTI4MTUgLTIxIC0zMCAzMSAtOSA0NzUxIDIxIDQ3NzMgMzAgMjEgNDQgMTcgNjIgLTE4IDkgLTE4IDI2IC00NCAzOCAtNTgKMjYgLTI5IDIyNSAtMzM4IDI1MSAtMzkwIDEwIC0xOSA0NCAtNzkgNzYgLTEzMyAzMyAtNTQgNTkgLTEwMCA1OSAtMTAyIDAgLTQKMTA2IC0xODcgMTc4IC0zMDUgMjUgLTQxIDc2IC0xMzEgMTE0IC0xOTkgMTU4IC0yODMgMjE4IC0zMjEgMzkxIC0yNDMgMTIxIDU1CjE1NCAxMTkgMTA5IDIwOSAtMjcgNTMgLTMyNCA1NTMgLTQxNyA3MDMgLTEyIDE5IC0zOSA2NCAtNTkgMTAwIC0yMCAzNiAtNDcKODMgLTYxIDEwNSAtMTMgMjIgLTMyIDU0IC00MSA3MCAtOSAxNyAtMzMgNTUgLTUzIDg1IC0yMSAzMCAtNTQgODcgLTc2IDEyNQotMTk1IDM1NSAtNDY1IDUyMCAtNzI1IDQ0MXogbS0yNjMgLTI2MTYgYy0zIC0xMzg2IC0zIC0xNDAwIC00MSAtMTQwMCAtMTIgMAotMjYgLTQgLTMxIC05IC0xMSAtOSAtNjExIC0yOTEgLTYyMSAtMjkxIC0zIDAgLTc2IC0zMyAtMTYyIC03NCAtODcgLTQxIC0xODIKLTg1IC0yMTIgLTk5IC0zMCAtMTMgLTEzOCAtNjMgLTI0MCAtMTA5IC0xMDIgLTQ3IC0yMTQgLTk4IC0yNTAgLTExMyAtMzYgLTE1Ci0xMDQgLTQ3IC0xNTEgLTcxIC0xMDQgLTUyIC0zNDUgLTE1NCAtMzY0IC0xNTQgLTQxIDAgMTMgMTIyIDIwNyA0NjUgMzAgNTUKODcgMTU5IDEyNiAyMzAgMzggNzIgODMgMTU1IDk5IDE4NSAxNyAzMCA3MCAxMjkgMTE4IDIyMCA0OCA5MSAxMDcgMTk5IDEzMAoyNDAgMjMgNDEgNTkgMTA5IDgwIDE1MCAyMSA0MSA2MSAxMTYgOTAgMTY1IDI5IDUwIDg2IDE1MyAxMjcgMjMwIDExMSAyMDYKMTQwIDI1OSAxNDggMjcwIDQgNiAyOSA1MyA1NSAxMDUgMjcgNTIgNTQgMTAyIDYwIDExMCA3IDggMzIgNTEgNTUgOTUgMjQgNDQKNTEgOTQgNjEgMTEyIDEwIDE3IDQzIDc4IDc0IDEzNSAzMSA1NyA2MCAxMTAgNjUgMTE4IDUgOCAzNCA2MCA2MyAxMTUgMzAgNTUKODEgMTUwIDExNSAyMTAgOTUgMTczIDI1MCA0NjEgMzA1IDU2NSA4NSAxNjMgODEgMTYwIDg5IDUwIDUgLTUyIDcgLTcwNSA1Ci0xNDUweiBtMSAtMjE0NSBjNCAtNDQ1IDIxIC00MDEgLTE1NiAtNDA4IC0zMzEgLTE0IC0xNTI3IC0xMyAtMTUyNyAxIDAgNyAyMwoyMSA1MCAzMSAyOCAxMCA4OCAzNSAxMzUgNTYgNDcgMjEgMTIxIDUyIDE2NSA3MCAxMTEgNDUgMjEzIDkwIDQwMCAxNzUgODggNDAKMTc0IDc4IDE5MCA4NSAxNyA3IDExMSA1MCAyMTAgOTUgOTkgNDYgMjA5IDk1IDI0NSAxMTAgMzYgMTUgMTAzIDQ2IDE1MCA2OAoxNDUgNjkgMTM1IDkwIDEzOCAtMjgzeiIvPgo8cGF0aCBkPSJNNzk2NiA3MzgwIGMtMTUzIC02MCAtMTc5IC0xODIgLTcyIC0zMzMgMTkzIC0yNzAgMzcwIC01OTcgNDQwIC04MTEKMTMgLTM5IDI5IC04NCAzNiAtMTAxIDIzIC01NSAyOCAtNzAgMzMgLTkwIDMgLTExIDEzIC00NSAyMiAtNzUgOSAtMzAgMjAgLTcxCjI1IC05MCA1IC0xOSAxNiAtNjQgMjUgLTEwMCA5IC0zNiAyMCAtODUgMjUgLTExMCA0IC0yNSAxNSAtODMgMjQgLTEzMCAxMDIKLTUzMiA0NCAtMTE4NCAtMTQ2IC0xNjYwIC02NSAtMTYxIC00NiAtMjU1IDYwIC0zMDkgMjQzIC0xMjQgMzk5IDEzMiA1MjIgODU0CjUwIDI5NyA1MCA3NzEgMCAxMDY3IC00NSAyNjQgLTUyIDI5OSAtOTggNDc5IC0xMjIgNDcyIC0zNDcgOTY5IC01NzcgMTI3NgotMTA0IDEzNyAtMjAyIDE3OCAtMzE5IDEzM3oiLz4KPHBhdGggZD0iTTcxODkgNjc1MyBjLTEzMyAtNjggLTEyNSAtMTgyIDMzIC00MjMgMTYzIC0yNDkgMjU3IC00NjQgMzQ1IC03OTAKMTAxIC0zNzcgODYgLTEwMTUgLTMzIC0xMzMzIC00NSAtMTIxIDU1IC0yNTAgMjA1IC0yNjUgMTcyIC0xNiAyNjkgMTk5IDMyMQo3MTYgMTkgMTk2IDcgNTY1IC0yNiA3MzcgLTg1IDQ1NCAtMjAyIDc3NiAtNDA3IDExMjMgLTE0MyAyNDEgLTI4MCAzMTQgLTQzOAoyMzV6Ii8+CjxwYXRoIGQ9Ik02NTQwIDYzMzAgYy0zMCAtMTAgLTE0MCAtNTkgLTI0NSAtMTEwIC0xMDQgLTUwIC0yMTUgLTEwMyAtMjQ1Ci0xMTcgLTMwIC0xNCAtMTM3IC02NSAtMjM4IC0xMTQgLTEwMSAtNDkgLTE4NSAtODkgLTE4NyAtODkgLTIgMCAtODMgLTM4Ci0xODAgLTg1IC05OCAtNDcgLTE3OSAtODUgLTE4MSAtODUgLTUgMCAtNTIgLTIyIC0yNTkgLTEyMCAtNjAgLTI5IC0xMzcgLTY1Ci0xNzAgLTgwIC0zMyAtMTUgLTkxIC00MiAtMTMwIC02MCAtMTAxIC00NiAtMjY0IC0xMjkgLTMwNyAtMTU2IC0xNTkgLTEwMQotMTggLTMxMCAxNjIgLTIzOSAxOSA3IDcxIDI2IDExNSA0MiA0NCAxNyAxNDEgNTUgMjE1IDg1IDc0IDMwIDE4MCA3MiAyMzUgOTMKNTUgMjEgMTU2IDYwIDIyNSA4OCA2OSAyNyAxNDggNTggMTc3IDY4IDI5IDEwIDY3IDI0IDg1IDMyIDE4IDkgMTEwIDQ1IDIwMwo4MiA5NCAzNiAxODQgNzIgMjAwIDc5IDE3IDcgNDYgMTkgNjUgMjYgMzEgMTEgNTYgMjEgMTI1IDUwIDExIDQgNTIgMjAgOTAgMzUKMzkgMTUgOTUgMzcgMTI1IDUwIDMwIDEzIDExMyA0NyAxODUgNzcgMjEzIDg3IDI2MCAxNjEgMTk5IDMxMyAtNTQgMTM1IC0xMzYKMTc3IC0yNjQgMTM1eiIvPgo8cGF0aCBkPSJNNjkwMCA1MjYzIGMtMzcgLTMgLTE5NCAtMjkgLTI3MCAtNDMgLTI1IC01IC04NSAtMTYgLTEzNSAtMjUgLTQ5Ci05IC0xMTAgLTIwIC0xMzUgLTI1IC0yNSAtNSAtODUgLTE2IC0xMzUgLTI1IC00OSAtOSAtMTM1IC0yNiAtMTkwIC0zNiAtNTUKLTExIC0xMjkgLTI0IC0xNjUgLTI5IC0zNiAtNSAtMTA1IC0xNiAtMTU1IC0yNSAtNDkgLTkgLTExNSAtMjAgLTE0NSAtMjUgLTMwCi01IC05OCAtMTggLTE1MCAtMjggLTUyIC0xMSAtMTI5IC0yNSAtMTcwIC0zMiAtNzUgLTEyIC0yMTYgLTQwIC0zNDAgLTY2IC0zNgotOCAtODggLTE4IC0xMTYgLTIzIC0xMzIgLTI0IC0xODYgLTk2IC0xMTAgLTE0NiAzNyAtMjUgMjQ1IC0zOCAzODMgLTI1IDYzIDYKMjA3IDE1IDMyMSAyMCA3NzQgMzYgMTM5NCA3NCAxNTAyIDkxIDM2IDUgNzggMTIgOTQgMTQgMjAzIDMzIDE4NCA0NDUgLTIwCjQzMyAtMTYgMCAtNDUgLTMgLTY0IC01eiIvPgo8L2c+Cjwvc3ZnPgo=&style=for-the-badge)](https://www.npmjs.com/package/prismcast)
10
+ [![Channels DVR](https://img.shields.io/badge/Channels%20DVR-Ready-636382?style=for-the-badge)](https://getchannels.com/)
11
+
12
+ ## Browser-based live TV capture for [Channels DVR](https://getchannels.com).
13
+
14
+ </DIV>
15
+ </SPAN>
16
+
17
+ PrismCast captures live video from web-based TV streaming sites and delivers it as HLS streams that [Channels DVR](https://getchannels.com/) can record and play back. It uses Google Chrome to navigate to streaming sites, captures the video output, and serves it on your network. Most channels require a cable or streaming TV subscription - log in once with your TV provider credentials and Chrome remembers your session for future use.
18
+
19
+ This project is inspired by and builds upon the excellent work of [Chrome Capture for Channels](https://github.com/fancybits/chrome-capture-for-channels) by the Channels DVR team. I'm grateful to them for creating the original foundation that made PrismCast possible.
20
+
21
+ The name PrismCast reflects what the project does: like a prism transforming light into a spectrum of colors, PrismCast takes video from diverse streaming sources and refracts it into a unified HLS format for your DVR.
22
+
23
+ ## A Note About This Project
24
+
25
+ PrismCast started as an experiment: could I create a complete, production-quality application using only AI tools? Every line of code in this project was written by AI (Claude), but built on a foundation of my existing open source projects, coding style, and design philosophy. The AI learned from my prior work and preferences to produce code that feels like mine—because in many ways, it is. The result is a modern, fully-featured streaming server that I use daily.
26
+
27
+ I share this not as a gimmick, but because I think it's genuinely interesting. The AI handled everything from the initial architecture to the nuanced edge cases of browser automation and video streaming. My role was to provide direction, review the output, and iterate on the design. It's been a fascinating collaboration between human taste and AI capability, and I hope the code quality speaks for itself.
28
+
29
+ ## Why PrismCast?
30
+
31
+ If you're already using Chrome Capture for Channels and it's working well for you, that's wonderful! There's no need to switch. However, if you're looking for something different, PrismCast offers a modern TypeScript codebase, a real-time web interface, intelligent recovery, and the flexibility to easily add your own channels. The site profile system makes it straightforward to add support for new streaming sites, and contributions are always welcome!
32
+
33
+ ## Features
34
+
35
+ ### Channels and Streaming
36
+ - **Preconfigured channels** - PrismCast comes ready to stream most major US television networks out of the box. Just authenticate with your TV provider and you're ready to go.
37
+ - **Custom channel support** - Easily add your own streaming sources through the web interface, from YouTube live streams to niche international channels. If a site plays video in Chrome, there's a good chance PrismCast can capture it.
38
+ - **Multiple concurrent streams** - Stream up to 10 channels simultaneously (configurable), perfect for recording multiple shows at once.
39
+ - **Session persistence** - Log in to your TV provider once and Chrome remembers your session across restarts.
40
+ - **Quality presets** - Choose from 480p to 4K with automatic adaptation to your display capabilities.
41
+
42
+ ### Web Interface
43
+ - **Real-time dashboard** - Monitor all active streams with live health status, duration, memory usage, and (when recording via Channels DVR) the name of the show being recorded.
44
+ - **Channel management** - Add, edit, and delete custom channels directly in the browser. No config files to edit.
45
+ - **Live log viewer** - Stream server logs in real-time with level filtering, perfect for troubleshooting.
46
+ - **Configuration UI** - Adjust all settings through an intuitive web interface with instant validation.
47
+ - **Dark mode** - Automatic dark theme based on your system preferences.
48
+ - **Backup and restore** - Download your settings and channels for safekeeping, restore them anytime.
49
+
50
+ ### Reliability
51
+ - **Intelligent playback recovery** - Issue-aware recovery system that chooses the right fix for different problems. Buffering issues get different treatment than paused playback.
52
+ - **Circuit breaker protection** - Streams that fail repeatedly are automatically terminated, preventing resource exhaustion.
53
+ - **Health monitoring** - Built-in `/health` endpoint for integration with monitoring systems.
54
+ - **Graceful degradation** - If your display can't support your chosen quality preset, PrismCast automatically uses the best available resolution.
55
+
56
+ ### Technical
57
+ - **Native HLS segmentation** - Built-in fMP4 segmenter with no external dependencies for segment generation.
58
+ - **Flexible capture modes** - Choose between FFmpeg-based capture (more stable for long recordings) or native Chrome capture (no dependencies).
59
+ - **Site profile system** - Data-driven configuration for handling different streaming sites. Profiles define how to enter fullscreen, handle iframes, manage multi-channel players, and more. Adding support for a new site often requires just a few lines of configuration.
60
+ - **Gracenote integration** - Channels can include station IDs for automatic guide data matching in Channels DVR.
61
+ - **Modern codebase** - Clean TypeScript with ESM modules, full type safety, and comprehensive documentation.
62
+
63
+ ## Requirements
64
+
65
+ - **macOS** - PrismCast is developed and tested on macOS. Linux and Windows may work but are untested.
66
+ - **Node.js 22** or later
67
+ - **Google Chrome** (PrismCast will try to find it automatically, or you can specify the path)
68
+ - **Channels DVR** (or any client that can consume HLS streams)
69
+
70
+ ## Installation
71
+
72
+ The recommended approach is to install PrismCast globally and run it as a system service:
73
+
74
+ ```sh
75
+ npm install -g prismcast
76
+ ```
77
+
78
+ Once installed, you can start PrismCast with:
79
+
80
+ ```sh
81
+ prismcast
82
+ ```
83
+
84
+ ### Running as a Service
85
+
86
+ For the best experience, install PrismCast as a service that starts automatically at login:
87
+
88
+ ```sh
89
+ prismcast service install
90
+ ```
91
+
92
+ This configures your system's service manager (launchd on macOS, systemd on Linux, Task Scheduler on Windows) to run PrismCast in the background.
93
+
94
+ Other service commands:
95
+
96
+ ```sh
97
+ prismcast service status # Check if the service is running
98
+ prismcast service stop # Stop the service
99
+ prismcast service start # Start the service
100
+ prismcast service restart # Restart the service
101
+ prismcast service uninstall # Remove the service
102
+ ```
103
+
104
+ ## Quick Start with Channels DVR
105
+
106
+ 1. **Start PrismCast** and open `http://localhost:5589` in your browser
107
+ 2. **Authenticate with your TV provider** - Click "Login" on any channel that requires authentication, complete the login in the browser window that opens, then click "Done"
108
+ 3. **Add to Channels DVR**:
109
+ - Go to Settings → Custom Channels → Add Source
110
+ - Select **M3U Playlist**
111
+ - Enter: `http://<your-prismcast-host>:5589/playlist`
112
+ - Set Stream Format to **HLS**
113
+
114
+ That's it! Your channels will appear in the Channels DVR guide.
115
+
116
+ ## Configuration
117
+
118
+ PrismCast includes a web-based configuration interface at `http://localhost:5589/#config`. From there you can:
119
+
120
+ - **Manage channels** - View all available channels, add your own custom channels, or override the defaults
121
+ - **Adjust quality settings** - Choose from presets like 720p, 1080p, or 4K
122
+ - **Configure HLS parameters** - Segment duration, buffer size, idle timeout
123
+ - **Tune recovery behavior** - Adjust how aggressively PrismCast recovers from playback issues
124
+ - **Backup and restore** - Download your configuration for safekeeping
125
+
126
+ Configuration is stored in `~/.prismcast/config.json` and your TV provider sessions are preserved in `~/.prismcast/chromedata/`.
127
+
128
+ ## Platform Support
129
+
130
+ **macOS** is the primary development and testing platform. PrismCast is thoroughly tested on macOS and should work reliably there.
131
+
132
+ **Linux and Windows** have built-in support (including service installation), but these platforms are not actively tested. If you'd like to use PrismCast on Linux or Windows, you're welcome to try it, but please understand that you may encounter issues that haven't been discovered yet. Bug reports and pull requests for these platforms are always appreciated!
133
+
134
+ ## Contributing
135
+
136
+ Contributions are welcome! Whether it's bug reports, feature requests, new channel definitions, or pull requests, I appreciate your interest in improving PrismCast. If you've got a streaming site that works well with PrismCast, consider submitting a pull request to add it to the preconfigured channels.
137
+
138
+ ## License
139
+
140
+ [ISC License](LICENSE.md)
141
+
142
+ Copyright (c) 2024-2026 HJD
143
+
144
+ ## Acknowledgments
145
+
146
+ Special thanks to the [Channels DVR](https://getchannels.com/) team for creating such a wonderful DVR platform and for their work on [Chrome Capture for Channels](https://github.com/fancybits/chrome-capture-for-channels), which inspired this project.
147
+
148
+ ## Development Dashboard
149
+
150
+ This is mostly of interest to the true developer nerds amongst us.
151
+
152
+ [![License](https://img.shields.io/npm/l/prismcast?color=636382&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pgo8IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDIwMDEwOTA0Ly9FTiIKICJodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAxL1JFQy1TVkctMjAwMTA5MDQvRFREL3N2ZzEwLmR0ZCI+CjxzdmcgdmVyc2lvbj0iMS4wIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiB3aWR0aD0iMTAwMCIgaGVpZ2h0PSIxMDAwIiB2aWV3Qm94PSIwIDAgMTAwMC4wMDAwMDAgMTAwMC4wMDAwMDAiCiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWlkWU1pZCBtZWV0Ij4KPG1ldGFkYXRhPgpDcmVhdGVkIGJ5IHBvdHJhY2UgMS4xNiwgd3JpdHRlbiBieSBQZXRlciBTZWxpbmdlciAyMDAxLTIwMTkKPC9tZXRhZGF0YT4KPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMC4wMDAwMDAsMTAwMC4wMDAwMDApIHNjYWxlKDAuMTAwMDAwLC0wLjEwMDAwMCkiCmZpbGw9IiM2MzYzODIiIHN0cm9rZT0ibm9uZSI+CjxwYXRoIGQ9Ik0zODYwIDc3OTYgYy0xNzkgLTUzIC0yMjEgLTEwMiAtNDYwIC01NDEgLTE4IC0zMyAtNjggLTEyMSAtMTEwCi0xOTUgLTQyIC03NCAtMTIxIC0yMTYgLTE3NSAtMzE1IC01NCAtOTkgLTExMiAtMjA1IC0xMzAgLTIzNSAtMTggLTMwIC00OQotODQgLTY3IC0xMjAgLTQwIC03NiAtMTI0IC0yMjcgLTE3OCAtMzIwIC01MyAtOTEgLTcwIC0xMjIgLTE3OCAtMzIwIC01MiAtOTYKLTk4IC0xNzkgLTEwMiAtMTg1IC00IC01IC0yOSAtNTAgLTU1IC0xMDAgLTI2IC00OSAtNzYgLTEzOSAtMTEwIC0yMDAgLTM0Ci02MCAtMTAwIC0xODAgLTE0NSAtMjY1IC00NiAtODUgLTg2IC0xNTkgLTkwIC0xNjUgLTUgLTUgLTI2IC00NSAtNDkgLTg4IC02OAotMTMwIC0xMjIgLTIyNyAtMTc3IC0zMjIgLTI4IC00OSAtOTggLTE3NSAtMTU0IC0yODAgLTEwMyAtMTkxIC0xMTkgLTIyMAotMjA0IC0zNzQgLTI1IC00NiAtNDYgLTg2IC00NiAtODggMCAtMyAtOCAtMTcgLTE5IC0zMSAtMTAgLTE1IC00NCAtNzYgLTc2Ci0xMzcgLTg1IC0xNjEgLTExMSAtMjA4IC0xODQgLTMzMCAtMzYgLTYwIC03NCAtMTMwIC04NSAtMTU1IC0xMCAtMjUgLTIxIC01MgotMjUgLTYwIC00NCAtODkgLTQ0IC0yODYgLTEgLTM2OSA0IC05IDIxIC00MyAzNiAtNzYgNjQgLTEzNiAyNDYgLTI3MSA0MTQKLTMwNiA5OCAtMjEgNTMxOCAtMjEgNTQwMCAwIDM5MyA5OSA1MzEgNDY3IDMyMyA4NjEgLTg3IDE2NCAtMzA0IDU1MSAtMzIzCjU3NSAtNCA2IC0xOCAzMCAtMzIgNTUgLTI0MyA0NDAgLTI2MyA0NzEgLTMzMCA1MDQgLTQ3IDIzIC05NCAzNCAtMzEzIDc2IC0yNwo1IC0xMDQgMTYgLTE3MCAyNSAtNjYgOSAtMTc4IDI2IC0yNTAgMzcgLTEzOCAyMSAtMTk5IDMwIC0zNjAgNTMgLTU1IDggLTEyOQoxOSAtMTY1IDI0IC0zNiA1IC0xMDEgMTQgLTE0NSAyMCAtNDQgNiAtMTA3IDE1IC0xNDAgMjEgLTMzIDUgLTk2IDE0IC0xNDAgMTkKLTQ0IDYgLTEzNiAxOCAtMjA0IDI3IC0zNzAgNDkgLTQ4MSAtMTAyIC0xNTEgLTIwNSA1OCAtMTggMTE2IC0zNyAxMzAgLTQyIDE0Ci00IDYxIC0xNyAxMDUgLTI4IDcyIC0xOCAxNTMgLTQwIDMyNSAtODcgMjQyIC02NyAyNDMgLTY3IDQxMCAtOTggNDcgLTkgMTAzCi0yMCAxMjUgLTI1IDIyIC01IDc2IC0xNyAxMjAgLTI2IDIyOCAtNDggNTIzIC0xMjAgNTY3IC0xMzcgMzEgLTExIDQwIC0yNAoxMDcgLTE0NiA3OSAtMTQyIDMwNiAtNTM0IDMzMyAtNTc0IDE2OSAtMjQ4IDIwNiAtNDM3IDk2IC00OTQgLTU0IC0yOCAtMjc4NwotNDggLTI4MTUgLTIxIC0zMCAzMSAtOSA0NzUxIDIxIDQ3NzMgMzAgMjEgNDQgMTcgNjIgLTE4IDkgLTE4IDI2IC00NCAzOCAtNTgKMjYgLTI5IDIyNSAtMzM4IDI1MSAtMzkwIDEwIC0xOSA0NCAtNzkgNzYgLTEzMyAzMyAtNTQgNTkgLTEwMCA1OSAtMTAyIDAgLTQKMTA2IC0xODcgMTc4IC0zMDUgMjUgLTQxIDc2IC0xMzEgMTE0IC0xOTkgMTU4IC0yODMgMjE4IC0zMjEgMzkxIC0yNDMgMTIxIDU1CjE1NCAxMTkgMTA5IDIwOSAtMjcgNTMgLTMyNCA1NTMgLTQxNyA3MDMgLTEyIDE5IC0zOSA2NCAtNTkgMTAwIC0yMCAzNiAtNDcKODMgLTYxIDEwNSAtMTMgMjIgLTMyIDU0IC00MSA3MCAtOSAxNyAtMzMgNTUgLTUzIDg1IC0yMSAzMCAtNTQgODcgLTc2IDEyNQotMTk1IDM1NSAtNDY1IDUyMCAtNzI1IDQ0MXogbS0yNjMgLTI2MTYgYy0zIC0xMzg2IC0zIC0xNDAwIC00MSAtMTQwMCAtMTIgMAotMjYgLTQgLTMxIC05IC0xMSAtOSAtNjExIC0yOTEgLTYyMSAtMjkxIC0zIDAgLTc2IC0zMyAtMTYyIC03NCAtODcgLTQxIC0xODIKLTg1IC0yMTIgLTk5IC0zMCAtMTMgLTEzOCAtNjMgLTI0MCAtMTA5IC0xMDIgLTQ3IC0yMTQgLTk4IC0yNTAgLTExMyAtMzYgLTE1Ci0xMDQgLTQ3IC0xNTEgLTcxIC0xMDQgLTUyIC0zNDUgLTE1NCAtMzY0IC0xNTQgLTQxIDAgMTMgMTIyIDIwNyA0NjUgMzAgNTUKODcgMTU5IDEyNiAyMzAgMzggNzIgODMgMTU1IDk5IDE4NSAxNyAzMCA3MCAxMjkgMTE4IDIyMCA0OCA5MSAxMDcgMTk5IDEzMAoyNDAgMjMgNDEgNTkgMTA5IDgwIDE1MCAyMSA0MSA2MSAxMTYgOTAgMTY1IDI5IDUwIDg2IDE1MyAxMjcgMjMwIDExMSAyMDYKMTQwIDI1OSAxNDggMjcwIDQgNiAyOSA1MyA1NSAxMDUgMjcgNTIgNTQgMTAyIDYwIDExMCA3IDggMzIgNTEgNTUgOTUgMjQgNDQKNTEgOTQgNjEgMTEyIDEwIDE3IDQzIDc4IDc0IDEzNSAzMSA1NyA2MCAxMTAgNjUgMTE4IDUgOCAzNCA2MCA2MyAxMTUgMzAgNTUKODEgMTUwIDExNSAyMTAgOTUgMTczIDI1MCA0NjEgMzA1IDU2NSA4NSAxNjMgODEgMTYwIDg5IDUwIDUgLTUyIDcgLTcwNSA1Ci0xNDUweiBtMSAtMjE0NSBjNCAtNDQ1IDIxIC00MDEgLTE1NiAtNDA4IC0zMzEgLTE0IC0xNTI3IC0xMyAtMTUyNyAxIDAgNyAyMwoyMSA1MCAzMSAyOCAxMCA4OCAzNSAxMzUgNTYgNDcgMjEgMTIxIDUyIDE2NSA3MCAxMTEgNDUgMjEzIDkwIDQwMCAxNzUgODggNDAKMTc0IDc4IDE5MCA4NSAxNyA3IDExMSA1MCAyMTAgOTUgOTkgNDYgMjA5IDk1IDI0NSAxMTAgMzYgMTUgMTAzIDQ2IDE1MCA2OAoxNDUgNjkgMTM1IDkwIDEzOCAtMjgzeiIvPgo8cGF0aCBkPSJNNzk2NiA3MzgwIGMtMTUzIC02MCAtMTc5IC0xODIgLTcyIC0zMzMgMTkzIC0yNzAgMzcwIC01OTcgNDQwIC04MTEKMTMgLTM5IDI5IC04NCAzNiAtMTAxIDIzIC01NSAyOCAtNzAgMzMgLTkwIDMgLTExIDEzIC00NSAyMiAtNzUgOSAtMzAgMjAgLTcxCjI1IC05MCA1IC0xOSAxNiAtNjQgMjUgLTEwMCA5IC0zNiAyMCAtODUgMjUgLTExMCA0IC0yNSAxNSAtODMgMjQgLTEzMCAxMDIKLTUzMiA0NCAtMTE4NCAtMTQ2IC0xNjYwIC02NSAtMTYxIC00NiAtMjU1IDYwIC0zMDkgMjQzIC0xMjQgMzk5IDEzMiA1MjIgODU0CjUwIDI5NyA1MCA3NzEgMCAxMDY3IC00NSAyNjQgLTUyIDI5OSAtOTggNDc5IC0xMjIgNDcyIC0zNDcgOTY5IC01NzcgMTI3NgotMTA0IDEzNyAtMjAyIDE3OCAtMzE5IDEzM3oiLz4KPHBhdGggZD0iTTcxODkgNjc1MyBjLTEzMyAtNjggLTEyNSAtMTgyIDMzIC00MjMgMTYzIC0yNDkgMjU3IC00NjQgMzQ1IC03OTAKMTAxIC0zNzcgODYgLTEwMTUgLTMzIC0xMzMzIC00NSAtMTIxIDU1IC0yNTAgMjA1IC0yNjUgMTcyIC0xNiAyNjkgMTk5IDMyMQo3MTYgMTkgMTk2IDcgNTY1IC0yNiA3MzcgLTg1IDQ1NCAtMjAyIDc3NiAtNDA3IDExMjMgLTE0MyAyNDEgLTI4MCAzMTQgLTQzOAoyMzV6Ii8+CjxwYXRoIGQ9Ik02NTQwIDYzMzAgYy0zMCAtMTAgLTE0MCAtNTkgLTI0NSAtMTEwIC0xMDQgLTUwIC0yMTUgLTEwMyAtMjQ1Ci0xMTcgLTMwIC0xNCAtMTM3IC02NSAtMjM4IC0xMTQgLTEwMSAtNDkgLTE4NSAtODkgLTE4NyAtODkgLTIgMCAtODMgLTM4Ci0xODAgLTg1IC05OCAtNDcgLTE3OSAtODUgLTE4MSAtODUgLTUgMCAtNTIgLTIyIC0yNTkgLTEyMCAtNjAgLTI5IC0xMzcgLTY1Ci0xNzAgLTgwIC0zMyAtMTUgLTkxIC00MiAtMTMwIC02MCAtMTAxIC00NiAtMjY0IC0xMjkgLTMwNyAtMTU2IC0xNTkgLTEwMQotMTggLTMxMCAxNjIgLTIzOSAxOSA3IDcxIDI2IDExNSA0MiA0NCAxNyAxNDEgNTUgMjE1IDg1IDc0IDMwIDE4MCA3MiAyMzUgOTMKNTUgMjEgMTU2IDYwIDIyNSA4OCA2OSAyNyAxNDggNTggMTc3IDY4IDI5IDEwIDY3IDI0IDg1IDMyIDE4IDkgMTEwIDQ1IDIwMwo4MiA5NCAzNiAxODQgNzIgMjAwIDc5IDE3IDcgNDYgMTkgNjUgMjYgMzEgMTEgNTYgMjEgMTI1IDUwIDExIDQgNTIgMjAgOTAgMzUKMzkgMTUgOTUgMzcgMTI1IDUwIDMwIDEzIDExMyA0NyAxODUgNzcgMjEzIDg3IDI2MCAxNjEgMTk5IDMxMyAtNTQgMTM1IC0xMzYKMTc3IC0yNjQgMTM1eiIvPgo8cGF0aCBkPSJNNjkwMCA1MjYzIGMtMzcgLTMgLTE5NCAtMjkgLTI3MCAtNDMgLTI1IC01IC04NSAtMTYgLTEzNSAtMjUgLTQ5Ci05IC0xMTAgLTIwIC0xMzUgLTI1IC0yNSAtNSAtODUgLTE2IC0xMzUgLTI1IC00OSAtOSAtMTM1IC0yNiAtMTkwIC0zNiAtNTUKLTExIC0xMjkgLTI0IC0xNjUgLTI5IC0zNiAtNSAtMTA1IC0xNiAtMTU1IC0yNSAtNDkgLTkgLTExNSAtMjAgLTE0NSAtMjUgLTMwCi01IC05OCAtMTggLTE1MCAtMjggLTUyIC0xMSAtMTI5IC0yNSAtMTcwIC0zMiAtNzUgLTEyIC0yMTYgLTQwIC0zNDAgLTY2IC0zNgotOCAtODggLTE4IC0xMTYgLTIzIC0xMzIgLTI0IC0xODYgLTk2IC0xMTAgLTE0NiAzNyAtMjUgMjQ1IC0zOCAzODMgLTI1IDYzIDYKMjA3IDE1IDMyMSAyMCA3NzQgMzYgMTM5NCA3NCAxNTAyIDkxIDM2IDUgNzggMTIgOTQgMTQgMjAzIDMzIDE4NCA0NDUgLTIwCjQzMyAtMTYgMCAtNDUgLTMgLTY0IC01eiIvPgo8L2c+Cjwvc3ZnPgo=&style=for-the-badge)](https://github.com/hjdhjd/prismcast/blob/main/LICENSE.md)
153
+ [![Build Status](https://img.shields.io/github/actions/workflow/status/hjdhjd/prismcast/ci.yml?color=636382&logo=github&logoColor=%23FFFFFF&style=for-the-badge)](https://github.com/hjdhjd/prismcast/actions?query=workflow%3A%22Continuous+Integration%22)
154
+ [![Dependencies](https://img.shields.io/librariesio/release/npm/prismcast?color=636382&logo=nodedotjs&logoColor=%23FFFFFF&style=for-the-badge)](https://libraries.io/npm/prismcast)
155
+ [![GitHub commits since latest release](https://img.shields.io/github/commits-since/hjdhjd/prismcast/latest?color=636382&logo=github&logoColor=%23FFFFFF&style=for-the-badge)](https://github.com/hjdhjd/prismcast/commits/main)
@@ -0,0 +1,71 @@
1
+ /* Copyright(C) 2024-2026, HJD (https://github.com/hjdhjd). All rights reserved.
2
+ *
3
+ * eslint.config.mjs: Linting configuration for PrismCast.
4
+ */
5
+ import eslintJs from "@eslint/js";
6
+ import hbPluginUtils from "homebridge-plugin-utils/build/eslint-rules.mjs";
7
+ import ts from "typescript-eslint";
8
+ import tsParser from "@typescript-eslint/parser";
9
+
10
+ export default ts.config(
11
+
12
+ eslintJs.configs.recommended,
13
+
14
+ {
15
+
16
+ files: ["src/**/*.ts"],
17
+ rules: {
18
+
19
+ ...hbPluginUtils.rules.ts
20
+ }
21
+ },
22
+
23
+ {
24
+
25
+ files: ["eslint.config.mjs"],
26
+ rules: {
27
+
28
+ ...hbPluginUtils.rules.js
29
+ }
30
+ },
31
+
32
+ {
33
+
34
+ files: [ "src/**/*.ts", "eslint.config.mjs" ],
35
+
36
+ ignores: ["dist"],
37
+
38
+ languageOptions: {
39
+
40
+ ecmaVersion: "latest",
41
+ parser: tsParser,
42
+ parserOptions: {
43
+
44
+ ecmaVersion: "latest",
45
+
46
+ projectService: {
47
+
48
+ allowDefaultProject: ["eslint.config.mjs"],
49
+ defaultProject: "./tsconfig.json"
50
+ }
51
+ },
52
+
53
+ sourceType: "module"
54
+ },
55
+
56
+ linterOptions: {
57
+
58
+ reportUnusedDisableDirectives: "error"
59
+ },
60
+
61
+ plugins: {
62
+
63
+ ...hbPluginUtils.plugins
64
+ },
65
+
66
+ rules: {
67
+
68
+ ...hbPluginUtils.rules.common
69
+ }
70
+ }
71
+ );
package/package.json CHANGED
@@ -1,10 +1,52 @@
1
1
  {
2
2
  "name": "prismcast",
3
- "version": "0.0.1",
4
- "description": "Placeholder.",
3
+ "displayName": "PrismCast",
4
+ "version": "1.0.0",
5
+ "description": "Browser-based live TV capture server for Channels DVR and other streaming clients.",
6
+ "author": {
7
+ "name": "HJD",
8
+ "url": "https://github.com/hjdhjd"
9
+ },
5
10
  "license": "ISC",
6
- "main": "index.js",
7
- "files": ["index.js", "README.md", "LICENSE"],
8
- "keywords": ["placeholder"],
9
- "private": false
11
+ "engines": {
12
+ "node": ">=22"
13
+ },
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git://github.com/hjdhjd/prismcast.git"
17
+ },
18
+ "type": "module",
19
+ "bin": {
20
+ "prismcast": "./bin/prismcast"
21
+ },
22
+ "main": "./dist/index.js",
23
+ "scripts": {
24
+ "build": "shx rm -rf dist && tsc",
25
+ "clean": "shx rm -rf dist",
26
+ "lint": "ESLINT_MAX_WARNINGS=${ESLINT_MAX_WARNINGS:--1} eslint src eslint.config.mjs",
27
+ "prepublishOnly": "npm run lint && npm run build",
28
+ "start": "node dist/index.js",
29
+ "watch": "npm run build && nodemon"
30
+ },
31
+ "dependencies": {
32
+ "console-stamp": "3.1.2",
33
+ "express": "5.2.1",
34
+ "ffmpeg-for-homebridge": "2.2.0",
35
+ "morgan": "1.10.1",
36
+ "puppeteer-core": "24.36.0",
37
+ "puppeteer-stream": "3.0.21"
38
+ },
39
+ "devDependencies": {
40
+ "@stylistic/eslint-plugin": "5.7.1",
41
+ "@types/dateformat": "5.0.3",
42
+ "@types/express": "5.0.6",
43
+ "@types/morgan": "1.9.10",
44
+ "@types/node": "25.0.10",
45
+ "eslint": "9.39.2",
46
+ "homebridge-plugin-utils": "1.31.0",
47
+ "nodemon": "3.1.11",
48
+ "shx": "0.4.0",
49
+ "typescript": "5.9.3",
50
+ "typescript-eslint": "8.53.1"
51
+ }
10
52
  }
package/prismcast.png ADDED
Binary file