@yume-chan/scrcpy-decoder-webcodecs 0.0.23 → 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 (100) hide show
  1. package/CHANGELOG.md +40 -2
  2. package/LICENSE +1 -1
  3. package/README.md +49 -29
  4. package/esm/index.d.ts +1 -20
  5. package/esm/index.d.ts.map +1 -1
  6. package/esm/index.js +1 -181
  7. package/esm/index.js.map +1 -1
  8. package/esm/video/codec/av1.d.ts +8 -0
  9. package/esm/video/codec/av1.d.ts.map +1 -0
  10. package/esm/video/codec/av1.js +71 -0
  11. package/esm/video/codec/av1.js.map +1 -0
  12. package/esm/video/codec/h264.d.ts +7 -0
  13. package/esm/video/codec/h264.d.ts.map +1 -0
  14. package/esm/video/codec/h264.js +27 -0
  15. package/esm/video/codec/h264.js.map +1 -0
  16. package/esm/video/codec/h265.d.ts +7 -0
  17. package/esm/video/codec/h265.d.ts.map +1 -0
  18. package/esm/video/codec/h265.js +33 -0
  19. package/esm/video/codec/h265.js.map +1 -0
  20. package/esm/video/codec/h26x.d.ts +9 -0
  21. package/esm/video/codec/h26x.d.ts.map +1 -0
  22. package/esm/video/codec/h26x.js +35 -0
  23. package/esm/video/codec/h26x.js.map +1 -0
  24. package/esm/video/codec/index.d.ts +7 -0
  25. package/esm/video/codec/index.d.ts.map +1 -0
  26. package/esm/video/codec/index.js +7 -0
  27. package/esm/video/codec/index.js.map +1 -0
  28. package/esm/video/codec/type.d.ts +8 -0
  29. package/esm/video/codec/type.d.ts.map +1 -0
  30. package/esm/video/codec/type.js +2 -0
  31. package/esm/video/codec/type.js.map +1 -0
  32. package/esm/video/codec/utils.d.ts +4 -0
  33. package/esm/video/codec/utils.d.ts.map +1 -0
  34. package/esm/video/codec/utils.js +10 -0
  35. package/esm/video/codec/utils.js.map +1 -0
  36. package/esm/video/decoder.d.ts +35 -0
  37. package/esm/video/decoder.d.ts.map +1 -0
  38. package/esm/video/decoder.js +240 -0
  39. package/esm/video/decoder.js.map +1 -0
  40. package/esm/video/index.d.ts +4 -0
  41. package/esm/video/index.d.ts.map +1 -0
  42. package/esm/video/index.js +4 -0
  43. package/esm/video/index.js.map +1 -0
  44. package/esm/video/render/bitmap.d.ts +7 -0
  45. package/esm/video/render/bitmap.d.ts.map +1 -0
  46. package/esm/video/render/bitmap.js +15 -0
  47. package/esm/video/render/bitmap.js.map +1 -0
  48. package/esm/video/render/canvas.d.ts +9 -0
  49. package/esm/video/render/canvas.d.ts.map +1 -0
  50. package/esm/video/render/canvas.js +22 -0
  51. package/esm/video/render/canvas.js.map +1 -0
  52. package/esm/video/render/index.d.ts +6 -0
  53. package/esm/video/render/index.d.ts.map +1 -0
  54. package/esm/video/render/index.js +7 -0
  55. package/esm/video/render/index.js.map +1 -0
  56. package/esm/video/render/insertable-stream.d.ts +10 -0
  57. package/esm/video/render/insertable-stream.d.ts.map +1 -0
  58. package/esm/video/render/insertable-stream.js +45 -0
  59. package/esm/video/render/insertable-stream.js.map +1 -0
  60. package/esm/video/render/type.d.ts +6 -0
  61. package/esm/video/render/type.d.ts.map +1 -0
  62. package/esm/video/render/type.js +2 -0
  63. package/esm/video/render/type.js.map +1 -0
  64. package/esm/video/render/webgl.d.ts +17 -0
  65. package/esm/video/render/webgl.d.ts.map +1 -0
  66. package/esm/{webgl.js → video/render/webgl.js} +47 -26
  67. package/esm/video/render/webgl.js.map +1 -0
  68. package/package.json +12 -17
  69. package/src/index.ts +1 -247
  70. package/src/video/codec/av1.ts +101 -0
  71. package/src/video/codec/h264.ts +42 -0
  72. package/src/video/codec/h265.ts +50 -0
  73. package/src/video/codec/h26x.ts +45 -0
  74. package/src/video/codec/index.ts +6 -0
  75. package/src/video/codec/type.ts +12 -0
  76. package/src/video/codec/utils.ts +11 -0
  77. package/src/video/decoder.ts +307 -0
  78. package/src/video/index.ts +3 -0
  79. package/src/video/render/bitmap.ts +18 -0
  80. package/src/video/render/canvas.ts +29 -0
  81. package/src/video/render/index.ts +7 -0
  82. package/src/video/render/insertable-stream.ts +62 -0
  83. package/src/video/render/type.ts +7 -0
  84. package/src/{webgl.ts → video/render/webgl.ts} +67 -30
  85. package/tsconfig.build.json +4 -1
  86. package/tsconfig.build.tsbuildinfo +1 -1
  87. package/CHANGELOG.json +0 -74
  88. package/esm/bitmap.d.ts +0 -7
  89. package/esm/bitmap.d.ts.map +0 -1
  90. package/esm/bitmap.js +0 -17
  91. package/esm/bitmap.js.map +0 -1
  92. package/esm/renderer.d.ts +0 -4
  93. package/esm/renderer.d.ts.map +0 -1
  94. package/esm/renderer.js +0 -2
  95. package/esm/renderer.js.map +0 -1
  96. package/esm/webgl.d.ts +0 -9
  97. package/esm/webgl.d.ts.map +0 -1
  98. package/esm/webgl.js.map +0 -1
  99. package/src/bitmap.ts +0 -24
  100. package/src/renderer.ts +0 -3
package/CHANGELOG.md CHANGED
@@ -1,8 +1,41 @@
1
1
  # Change Log - @yume-chan/scrcpy-decoder-webcodecs
2
2
 
3
- This log was last generated on Thu, 21 Mar 2024 03:15:10 GMT and should not be manually modified.
3
+ ## 1.0.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 53688d3: Use PNPM workspace and Changesets to manage the monorepo.
8
+
9
+ Because Changesets doesn't support alpha versions (`0.x.x`), this version is `1.0.0`. Future versions will follow SemVer rules, for example, breaking API changes will introduce a new major version.
10
+
11
+ - db8466f: Fix H.265 rendering in Microsoft Edge
12
+ - 8e4c1ef: Add a renderer based on Insertable Stream API
13
+ - db8466f: Add a `snapshot` method to convert the last rendered frame into PNG
14
+ - Updated dependencies [53688d3]
15
+ - Updated dependencies [db8466f]
16
+ - Updated dependencies [db8466f]
17
+ - Updated dependencies [ea5002b]
18
+ - Updated dependencies [ea5002b]
19
+ - Updated dependencies [db8466f]
20
+ - @yume-chan/scrcpy-decoder-tinyh264@1.0.1
21
+ - @yume-chan/no-data-view@1.0.1
22
+ - @yume-chan/stream-extra@1.0.1
23
+ - @yume-chan/scrcpy@1.0.1
24
+ - @yume-chan/event@1.0.1
25
+
26
+ This log was last generated on Tue, 18 Jun 2024 02:49:43 GMT and should not be manually modified.
27
+
28
+ ## 0.0.24
29
+
30
+ Tue, 18 Jun 2024 02:49:43 GMT
31
+
32
+ ### Updates
33
+
34
+ - Support decoding AV1
35
+ - Add `enableCapture` option to `WebCodecsVideoDecoder` which allows `renderer.readPixels` and `renderer.toDataURL` to work. The performance will be slightly affected when enabled.
4
36
 
5
37
  ## 0.0.23
38
+
6
39
  Thu, 21 Mar 2024 03:15:10 GMT
7
40
 
8
41
  ### Updates
@@ -11,16 +44,19 @@ Thu, 21 Mar 2024 03:15:10 GMT
11
44
  - Add WebGL and Bitmap based video renderers, which are 1.5 to 3 times faster on Android devices
12
45
 
13
46
  ## 0.0.22
47
+
14
48
  Wed, 13 Dec 2023 05:57:27 GMT
15
49
 
16
50
  _Version update only_
17
51
 
18
52
  ## 0.0.21
53
+
19
54
  Fri, 25 Aug 2023 14:05:18 GMT
20
55
 
21
56
  _Version update only_
22
57
 
23
58
  ## 0.0.20
59
+
24
60
  Mon, 05 Jun 2023 02:51:41 GMT
25
61
 
26
62
  ### Updates
@@ -28,11 +64,13 @@ Mon, 05 Jun 2023 02:51:41 GMT
28
64
  - Add support for decoding H.265 on supported browsers (Chrome works, Microsoft Edge with HEVC Video Extension from Microsoft Store doesn't decode H.265 correctly).
29
65
 
30
66
  ## 0.0.19
67
+
31
68
  Sun, 09 Apr 2023 05:55:33 GMT
32
69
 
33
70
  _Version update only_
34
71
 
35
72
  ## 0.0.18
73
+
36
74
  Wed, 25 Jan 2023 21:33:49 GMT
37
75
 
38
76
  ### Updates
@@ -40,9 +78,9 @@ Wed, 25 Jan 2023 21:33:49 GMT
40
78
  - Change to not use vertical sync to minimize latency
41
79
 
42
80
  ## 0.0.17
81
+
43
82
  Tue, 18 Oct 2022 09:32:30 GMT
44
83
 
45
84
  ### Updates
46
85
 
47
86
  - Separated from `@yume-chan/scrcpy` for simpler dependency management.
48
-
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2020-2023 Simon Chan
3
+ Copyright (c) 2020-2024 Simon Chan
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,29 +1,49 @@
1
- # @yume-chan/scrcpy-decoder-webcodecs
2
-
3
- Decode and render H.264 streams using the [WebCodecs API](https://developer.mozilla.org/en-US/docs/Web/API/WebCodecs_API).
4
-
5
- It has no dependencies and high performance, but is only available on recent versions of Chrome.
6
-
7
- **WARNING:** The public API is UNSTABLE. Open a GitHub discussion if you have any questions.
8
-
9
- - [Compatibility](#compatibility)
10
- - [Usage](#usage)
11
-
12
- ## Compatibility
13
-
14
- | Chrome | Firefox | Safari | Performance | Supported H.264 profile/level |
15
- | ------ | ------- | ------ | ------------------------------- | ----------------------------- |
16
- | 94 | No | No | High with hardware acceleration | High level 5 |
17
-
18
- ## Usage
19
-
20
- It draws frames onto `decoder.renderer` (a `<canvas>` element), you can insert it anywhere you want to display the video.
21
-
22
- ```ts
23
- const decoder = new WebCodecsDecoder();
24
- document.body.appendChild(decoder.renderer);
25
-
26
- videoPacketStream // from `@yume-chan/scrcpy`
27
- .pipeTo(decoder.writable)
28
- .catch(() => {});
29
- ```
1
+ <p align="center">
2
+ <img alt="Tango" src="https://raw.githubusercontent.com/yume-chan/ya-webadb/main/.github/logo.svg" width="200">
3
+ </p>
4
+
5
+ <h1 align="center">@yume-chan/scrcpy-decoder-webcodecs</h1>
6
+
7
+ <p align="center">
8
+ Raw H.264 stream decoder and renderer using WebCodecs API (requires modern browser).
9
+ </p>
10
+
11
+ <p align="center">
12
+ <a href="https://github.com/yume-chan/ya-webadb/blob/main/LICENSE">
13
+ <img alt="MIT License" src="https://img.shields.io/github/license/yume-chan/ya-webadb">
14
+ </a>
15
+ <a href="https://github.com/yume-chan/ya-webadb/releases">
16
+ <img alt="GitHub release" src="https://img.shields.io/github/v/release/yume-chan/ya-webadb?logo=github">
17
+ </a>
18
+ <a href="https://bundlephobia.com/package/@yume-chan/scrcpy-decoder-webcodecs">
19
+ <img alt="Package Size" src="https://img.shields.io/bundlephobia/minzip/%40yume-chan%2Fscrcpy-decoder-webcodecs">
20
+ </a>
21
+ <a href="https://www.npmjs.com/package/@yume-chan/scrcpy-decoder-webcodecs">
22
+ <img alt="npm" src="https://img.shields.io/npm/dm/%40yume-chan/scrcpy-decoder-webcodecs?logo=npm">
23
+ </a>
24
+ <a href="https://discord.gg/26k3ttC2PN">
25
+ <img alt="Discord" src="https://img.shields.io/discord/1120215514732564502?logo=discord&logoColor=%23ffffff&label=Discord">
26
+ </a>
27
+ </p>
28
+
29
+ This package is part of [Tango ADB](https://github.com/yume-chan/ya-webadb). Generally you need multiple packages to build a complete ADB client that can run on Web browsers and Node.js. Read the documentation for more information.
30
+
31
+ ## Documentation
32
+
33
+ Check the latest documentation at https://docs.tangoapp.dev/scrcpy/video/web-codecs/
34
+
35
+ ## Sponsors
36
+
37
+ [Become a backer](https://opencollective.com/ya-webadb) and get your image on our README on Github with a link to your site.
38
+
39
+ <a href="https://opencollective.com/ya-webadb/backer/0/website?requireActive=false" target="_blank"><img src="https://opencollective.com/ya-webadb/backer/0/avatar.svg?requireActive=false"></a>
40
+ <a href="https://opencollective.com/ya-webadb/backer/1/website?requireActive=false" target="_blank"><img src="https://opencollective.com/ya-webadb/backer/1/avatar.svg?requireActive=false"></a>
41
+ <a href="https://opencollective.com/ya-webadb/backer/2/website?requireActive=false" target="_blank"><img src="https://opencollective.com/ya-webadb/backer/2/avatar.svg?requireActive=false"></a>
42
+ <a href="https://opencollective.com/ya-webadb/backer/3/website?requireActive=false" target="_blank"><img src="https://opencollective.com/ya-webadb/backer/3/avatar.svg?requireActive=false"></a>
43
+ <a href="https://opencollective.com/ya-webadb/backer/4/website?requireActive=false" target="_blank"><img src="https://opencollective.com/ya-webadb/backer/4/avatar.svg?requireActive=false"></a>
44
+ <a href="https://opencollective.com/ya-webadb/backer/5/website?requireActive=false" target="_blank"><img src="https://opencollective.com/ya-webadb/backer/5/avatar.svg?requireActive=false"></a>
45
+ <a href="https://opencollective.com/ya-webadb/backer/6/website?requireActive=false" target="_blank"><img src="https://opencollective.com/ya-webadb/backer/6/avatar.svg?requireActive=false"></a>
46
+ <a href="https://opencollective.com/ya-webadb/backer/7/website?requireActive=false" target="_blank"><img src="https://opencollective.com/ya-webadb/backer/7/avatar.svg?requireActive=false"></a>
47
+ <a href="https://opencollective.com/ya-webadb/backer/8/website?requireActive=false" target="_blank"><img src="https://opencollective.com/ya-webadb/backer/8/avatar.svg?requireActive=false"></a>
48
+ <a href="https://opencollective.com/ya-webadb/backer/9/website?requireActive=false" target="_blank"><img src="https://opencollective.com/ya-webadb/backer/9/avatar.svg?requireActive=false"></a>
49
+ <a href="https://opencollective.com/ya-webadb/backer/10/website?requireActive=false" target="_blank"><img src="https://opencollective.com/ya-webadb/backer/10/avatar.svg?requireActive=false"></a>
package/esm/index.d.ts CHANGED
@@ -1,21 +1,2 @@
1
- import type { ScrcpyMediaStreamPacket } from "@yume-chan/scrcpy";
2
- import { ScrcpyVideoCodecId } from "@yume-chan/scrcpy";
3
- import type { ScrcpyVideoDecoder, ScrcpyVideoDecoderCapability } from "@yume-chan/scrcpy-decoder-tinyh264";
4
- import { WritableStream } from "@yume-chan/stream-extra";
5
- export declare class WebCodecsDecoder implements ScrcpyVideoDecoder {
6
- #private;
7
- static isSupported(): boolean;
8
- static readonly capabilities: Record<string, ScrcpyVideoDecoderCapability>;
9
- get codec(): ScrcpyVideoCodecId;
10
- get writable(): WritableStream<ScrcpyMediaStreamPacket>;
11
- get renderer(): HTMLCanvasElement;
12
- get frameRendered(): number;
13
- get frameSkipped(): number;
14
- get sizeChanged(): import("@yume-chan/event").AddEventListener<{
15
- width: number;
16
- height: number;
17
- }, unknown>;
18
- constructor(codec: ScrcpyVideoCodecId);
19
- dispose(): void;
20
- }
1
+ export * from "./video/index.js";
21
2
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAER,uBAAuB,EAC1B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACH,kBAAkB,EAGrB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EACR,kBAAkB,EAClB,4BAA4B,EAC/B,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAmBzD,qBAAa,gBAAiB,YAAW,kBAAkB;;IACvD,MAAM,CAAC,WAAW;IAIlB,MAAM,CAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,4BAA4B,CAAC,CAIpE;IAGN,IAAI,KAAK,uBAER;IAGD,IAAI,QAAQ,4CAEX;IAGD,IAAI,QAAQ,sBAEX;IAGD,IAAI,aAAa,WAEhB;IAGD,IAAI,YAAY,WAEf;IAGD,IAAI,WAAW;;;gBAEd;gBASW,KAAK,EAAE,kBAAkB;IA+JrC,OAAO;CAMV"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC"}
package/esm/index.js CHANGED
@@ -1,182 +1,2 @@
1
- import { EventEmitter } from "@yume-chan/event";
2
- import { ScrcpyVideoCodecId, h264ParseConfiguration, h265ParseConfiguration, } from "@yume-chan/scrcpy";
3
- import { WritableStream } from "@yume-chan/stream-extra";
4
- import { BitmapFrameRenderer } from "./bitmap.js";
5
- import { WebGLFrameRenderer } from "./webgl.js";
6
- function toHex(value) {
7
- return value.toString(16).padStart(2, "0").toUpperCase();
8
- }
9
- function toUint32Le(data, offset) {
10
- return (data[offset] |
11
- (data[offset + 1] << 8) |
12
- (data[offset + 2] << 16) |
13
- (data[offset + 3] << 24));
14
- }
15
- export class WebCodecsDecoder {
16
- static isSupported() {
17
- return typeof globalThis.VideoDecoder !== "undefined";
18
- }
19
- static capabilities = {
20
- h264: {},
21
- h265: {},
22
- };
23
- #codec;
24
- get codec() {
25
- return this.#codec;
26
- }
27
- #writable;
28
- get writable() {
29
- return this.#writable;
30
- }
31
- #canvas;
32
- get renderer() {
33
- return this.#canvas;
34
- }
35
- #frameRendered = 0;
36
- get frameRendered() {
37
- return this.#frameRendered;
38
- }
39
- #frameSkipped = 0;
40
- get frameSkipped() {
41
- return this.#frameSkipped;
42
- }
43
- #sizeChanged = new EventEmitter();
44
- get sizeChanged() {
45
- return this.#sizeChanged.event;
46
- }
47
- #decoder;
48
- #config;
49
- #renderer;
50
- #currentFrameRendered = false;
51
- #animationFrameId = 0;
52
- constructor(codec) {
53
- this.#codec = codec;
54
- this.#canvas = document.createElement("canvas");
55
- try {
56
- this.#renderer = new WebGLFrameRenderer(this.#canvas);
57
- }
58
- catch {
59
- this.#renderer = new BitmapFrameRenderer(this.#canvas);
60
- }
61
- this.#decoder = new VideoDecoder({
62
- output: (frame) => {
63
- if (this.#currentFrameRendered) {
64
- this.#frameRendered += 1;
65
- }
66
- else {
67
- this.#frameSkipped += 1;
68
- }
69
- this.#currentFrameRendered = false;
70
- // PERF: H.264 renderer may draw multiple frames in one vertical sync interval to minimize latency.
71
- // When multiple frames are drawn in one vertical sync interval,
72
- // only the last one is visible to users.
73
- // But this ensures users can always see the most up-to-date screen.
74
- // This is also the behavior of official Scrcpy client.
75
- // https://github.com/Genymobile/scrcpy/issues/3679
76
- this.#renderer.draw(frame);
77
- },
78
- error(e) {
79
- console.warn("[@yume-chan/scrcpy-decoder-webcodecs]", "VideoDecoder error", e);
80
- },
81
- });
82
- this.#writable = new WritableStream({
83
- write: (packet) => {
84
- switch (packet.type) {
85
- case "configuration":
86
- this.#configure(packet.data);
87
- break;
88
- case "data":
89
- this.#decode(packet);
90
- break;
91
- }
92
- },
93
- });
94
- this.#onFramePresented();
95
- }
96
- #onFramePresented = () => {
97
- this.#currentFrameRendered = true;
98
- this.#animationFrameId = requestAnimationFrame(this.#onFramePresented);
99
- };
100
- #configure(data) {
101
- switch (this.#codec) {
102
- case ScrcpyVideoCodecId.H264: {
103
- const { profileIndex, constraintSet, levelIndex, croppedWidth, croppedHeight, } = h264ParseConfiguration(data);
104
- this.#canvas.width = croppedWidth;
105
- this.#canvas.height = croppedHeight;
106
- this.#sizeChanged.fire({
107
- width: croppedWidth,
108
- height: croppedHeight,
109
- });
110
- // https://www.rfc-editor.org/rfc/rfc6381#section-3.3
111
- // ISO Base Media File Format Name Space
112
- const codec = `avc1.${[profileIndex, constraintSet, levelIndex]
113
- .map(toHex)
114
- .join("")}`;
115
- this.#decoder.configure({
116
- codec: codec,
117
- optimizeForLatency: true,
118
- });
119
- break;
120
- }
121
- case ScrcpyVideoCodecId.H265: {
122
- const { generalProfileSpace, generalProfileIndex, generalProfileCompatibilitySet, generalTierFlag, generalLevelIndex, generalConstraintSet, croppedWidth, croppedHeight, } = h265ParseConfiguration(data);
123
- this.#canvas.width = croppedWidth;
124
- this.#canvas.height = croppedHeight;
125
- this.#sizeChanged.fire({
126
- width: croppedWidth,
127
- height: croppedHeight,
128
- });
129
- const codec = [
130
- "hev1",
131
- ["", "A", "B", "C"][generalProfileSpace] +
132
- generalProfileIndex.toString(),
133
- toUint32Le(generalProfileCompatibilitySet, 0).toString(16),
134
- (generalTierFlag ? "H" : "L") +
135
- generalLevelIndex.toString(),
136
- toUint32Le(generalConstraintSet, 0)
137
- .toString(16)
138
- .toUpperCase(),
139
- toUint32Le(generalConstraintSet, 4)
140
- .toString(16)
141
- .toUpperCase(),
142
- ].join(".");
143
- this.#decoder.configure({
144
- codec,
145
- optimizeForLatency: true,
146
- });
147
- break;
148
- }
149
- }
150
- this.#config = data;
151
- }
152
- #decode(packet) {
153
- if (this.#decoder.state !== "configured") {
154
- return;
155
- }
156
- // WebCodecs requires configuration data to be with the first frame.
157
- // https://www.w3.org/TR/webcodecs-avc-codec-registration/#encodedvideochunk-type
158
- let data;
159
- if (this.#config !== undefined) {
160
- data = new Uint8Array(this.#config.byteLength + packet.data.byteLength);
161
- data.set(this.#config, 0);
162
- data.set(packet.data, this.#config.byteLength);
163
- this.#config = undefined;
164
- }
165
- else {
166
- data = packet.data;
167
- }
168
- this.#decoder.decode(new EncodedVideoChunk({
169
- // Treat `undefined` as `key`, otherwise won't decode.
170
- type: packet.keyframe === false ? "delta" : "key",
171
- timestamp: 0,
172
- data,
173
- }));
174
- }
175
- dispose() {
176
- cancelAnimationFrame(this.#animationFrameId);
177
- if (this.#decoder.state !== "closed") {
178
- this.#decoder.close();
179
- }
180
- }
181
- }
1
+ export * from "./video/index.js";
182
2
  //# sourceMappingURL=index.js.map
package/esm/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { ScrcpyMediaStreamPacket } from "@yume-chan/scrcpy";
2
+ import type { CodecDecoder } from "./type.js";
3
+ export declare class Av1Codec implements CodecDecoder {
4
+ #private;
5
+ constructor(decoder: VideoDecoder, updateSize: (width: number, height: number) => void);
6
+ decode(packet: ScrcpyMediaStreamPacket): void;
7
+ }
8
+ //# sourceMappingURL=av1.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"av1.d.ts","sourceRoot":"","sources":["../../../src/video/codec/av1.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAGjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAG9C,qBAAa,QAAS,YAAW,YAAY;;gBAKrC,OAAO,EAAE,YAAY,EACrB,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI;IAyEvD,MAAM,CAAC,MAAM,EAAE,uBAAuB,GAAG,IAAI;CAehD"}
@@ -0,0 +1,71 @@
1
+ import { Av1 } from "@yume-chan/scrcpy";
2
+ import { decimalTwoDigits } from "./utils.js";
3
+ export class Av1Codec {
4
+ #decoder;
5
+ #updateSize;
6
+ constructor(decoder, updateSize) {
7
+ this.#decoder = decoder;
8
+ this.#updateSize = updateSize;
9
+ }
10
+ #configure(data) {
11
+ const parser = new Av1(data);
12
+ const sequenceHeader = parser.searchSequenceHeaderObu();
13
+ if (!sequenceHeader) {
14
+ return;
15
+ }
16
+ const { seq_profile: seqProfile, seq_level_idx: [seqLevelIdx = 0], max_frame_width_minus_1, max_frame_height_minus_1, color_config: { BitDepth, mono_chrome: monoChrome, subsampling_x: subsamplingX, subsampling_y: subsamplingY, chroma_sample_position: chromaSamplePosition, color_description_present_flag, }, } = sequenceHeader;
17
+ let colorPrimaries;
18
+ let transferCharacteristics;
19
+ let matrixCoefficients;
20
+ let colorRange;
21
+ if (color_description_present_flag) {
22
+ ({
23
+ color_primaries: colorPrimaries,
24
+ transfer_characteristics: transferCharacteristics,
25
+ matrix_coefficients: matrixCoefficients,
26
+ color_range: colorRange,
27
+ } = sequenceHeader.color_config);
28
+ }
29
+ else {
30
+ colorPrimaries = Av1.ColorPrimaries.Bt709;
31
+ transferCharacteristics = Av1.TransferCharacteristics.Bt709;
32
+ matrixCoefficients = Av1.MatrixCoefficients.Bt709;
33
+ colorRange = false;
34
+ }
35
+ const width = max_frame_width_minus_1 + 1;
36
+ const height = max_frame_height_minus_1 + 1;
37
+ this.#updateSize(width, height);
38
+ const codec = [
39
+ "av01",
40
+ seqProfile.toString(16),
41
+ decimalTwoDigits(seqLevelIdx) +
42
+ (sequenceHeader.seq_tier[0] ? "H" : "M"),
43
+ decimalTwoDigits(BitDepth),
44
+ monoChrome ? "1" : "0",
45
+ (subsamplingX ? "1" : "0") +
46
+ (subsamplingY ? "1" : "0") +
47
+ chromaSamplePosition.toString(),
48
+ decimalTwoDigits(colorPrimaries),
49
+ decimalTwoDigits(transferCharacteristics),
50
+ decimalTwoDigits(matrixCoefficients),
51
+ colorRange ? "1" : "0",
52
+ ].join(".");
53
+ this.#decoder.configure({
54
+ codec,
55
+ optimizeForLatency: true,
56
+ });
57
+ }
58
+ decode(packet) {
59
+ if (packet.type === "configuration") {
60
+ return;
61
+ }
62
+ this.#configure(packet.data);
63
+ this.#decoder.decode(new EncodedVideoChunk({
64
+ // Treat `undefined` as `key`, otherwise it won't decode.
65
+ type: packet.keyframe === false ? "delta" : "key",
66
+ timestamp: 0,
67
+ data: packet.data,
68
+ }));
69
+ }
70
+ }
71
+ //# sourceMappingURL=av1.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"av1.js","sourceRoot":"","sources":["../../../src/video/codec/av1.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { H26xDecoder } from "./h26x.js";
2
+ export declare class H264Decoder extends H26xDecoder {
3
+ #private;
4
+ constructor(decoder: VideoDecoder, updateSize: (width: number, height: number) => void);
5
+ configure(data: Uint8Array): void;
6
+ }
7
+ //# sourceMappingURL=h264.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"h264.d.ts","sourceRoot":"","sources":["../../../src/video/codec/h264.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAGxC,qBAAa,WAAY,SAAQ,WAAW;;gBAKpC,OAAO,EAAE,YAAY,EACrB,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI;IAO9C,SAAS,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI;CAuB7C"}
@@ -0,0 +1,27 @@
1
+ import { h264ParseConfiguration } from "@yume-chan/scrcpy";
2
+ import { H26xDecoder } from "./h26x.js";
3
+ import { hexTwoDigits } from "./utils.js";
4
+ export class H264Decoder extends H26xDecoder {
5
+ #decoder;
6
+ #updateSize;
7
+ constructor(decoder, updateSize) {
8
+ super(decoder);
9
+ this.#decoder = decoder;
10
+ this.#updateSize = updateSize;
11
+ }
12
+ configure(data) {
13
+ const { profileIndex, constraintSet, levelIndex, croppedWidth, croppedHeight, } = h264ParseConfiguration(data);
14
+ this.#updateSize(croppedWidth, croppedHeight);
15
+ // https://www.rfc-editor.org/rfc/rfc6381#section-3.3
16
+ // ISO Base Media File Format Name Space
17
+ const codec = "avc1." +
18
+ hexTwoDigits(profileIndex) +
19
+ hexTwoDigits(constraintSet) +
20
+ hexTwoDigits(levelIndex);
21
+ this.#decoder.configure({
22
+ codec: codec,
23
+ optimizeForLatency: true,
24
+ });
25
+ }
26
+ }
27
+ //# sourceMappingURL=h264.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"h264.js","sourceRoot":"","sources":["../../../src/video/codec/h264.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAE3D,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,OAAO,WAAY,SAAQ,WAAW;IACxC,QAAQ,CAAe;IACvB,WAAW,CAA0C;IAErD,YACI,OAAqB,EACrB,UAAmD;QAEnD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;QACxB,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC;IAClC,CAAC;IAEQ,SAAS,CAAC,IAAgB;QAC/B,MAAM,EACF,YAAY,EACZ,aAAa,EACb,UAAU,EACV,YAAY,EACZ,aAAa,GAChB,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAC;QAEjC,IAAI,CAAC,WAAW,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;QAE9C,qDAAqD;QACrD,wCAAwC;QACxC,MAAM,KAAK,GACP,OAAO;YACP,YAAY,CAAC,YAAY,CAAC;YAC1B,YAAY,CAAC,aAAa,CAAC;YAC3B,YAAY,CAAC,UAAU,CAAC,CAAC;QAC7B,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;YACpB,KAAK,EAAE,KAAK;YACZ,kBAAkB,EAAE,IAAI;SAC3B,CAAC,CAAC;IACP,CAAC;CACJ"}
@@ -0,0 +1,7 @@
1
+ import { H26xDecoder } from "./h26x.js";
2
+ export declare class H265Decoder extends H26xDecoder {
3
+ #private;
4
+ constructor(decoder: VideoDecoder, updateSize: (width: number, height: number) => void);
5
+ configure(data: Uint8Array): void;
6
+ }
7
+ //# sourceMappingURL=h265.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"h265.d.ts","sourceRoot":"","sources":["../../../src/video/codec/h265.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAGxC,qBAAa,WAAY,SAAQ,WAAW;;gBAKpC,OAAO,EAAE,YAAY,EACrB,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI;IAO9C,SAAS,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI;CA8B7C"}
@@ -0,0 +1,33 @@
1
+ import { getUint32LittleEndian } from "@yume-chan/no-data-view";
2
+ import { h265ParseConfiguration } from "@yume-chan/scrcpy";
3
+ import { H26xDecoder } from "./h26x.js";
4
+ import { hexDigits } from "./utils.js";
5
+ export class H265Decoder extends H26xDecoder {
6
+ #decoder;
7
+ #updateSize;
8
+ constructor(decoder, updateSize) {
9
+ super(decoder);
10
+ this.#decoder = decoder;
11
+ this.#updateSize = updateSize;
12
+ }
13
+ configure(data) {
14
+ const { generalProfileSpace, generalProfileIndex, generalProfileCompatibilitySet, generalTierFlag, generalLevelIndex, generalConstraintSet, croppedWidth, croppedHeight, } = h265ParseConfiguration(data);
15
+ this.#updateSize(croppedWidth, croppedHeight);
16
+ const codec = [
17
+ "hev1",
18
+ ["", "A", "B", "C"][generalProfileSpace] +
19
+ generalProfileIndex.toString(),
20
+ hexDigits(getUint32LittleEndian(generalProfileCompatibilitySet, 0)),
21
+ (generalTierFlag ? "H" : "L") + generalLevelIndex.toString(),
22
+ ...Array.from(generalConstraintSet, hexDigits),
23
+ ].join(".");
24
+ this.#decoder.configure({
25
+ codec,
26
+ // Microsoft Edge requires explicit size to work
27
+ codedWidth: croppedWidth,
28
+ codedHeight: croppedHeight,
29
+ optimizeForLatency: true,
30
+ });
31
+ }
32
+ }
33
+ //# sourceMappingURL=h265.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"h265.js","sourceRoot":"","sources":["../../../src/video/codec/h265.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAE3D,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,OAAO,WAAY,SAAQ,WAAW;IACxC,QAAQ,CAAe;IACvB,WAAW,CAA0C;IAErD,YACI,OAAqB,EACrB,UAAmD;QAEnD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;QACxB,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC;IAClC,CAAC;IAEQ,SAAS,CAAC,IAAgB;QAC/B,MAAM,EACF,mBAAmB,EACnB,mBAAmB,EACnB,8BAA8B,EAC9B,eAAe,EACf,iBAAiB,EACjB,oBAAoB,EACpB,YAAY,EACZ,aAAa,GAChB,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAC;QAEjC,IAAI,CAAC,WAAW,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;QAE9C,MAAM,KAAK,GAAG;YACV,MAAM;YACN,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,mBAAmB,CAAE;gBACrC,mBAAmB,CAAC,QAAQ,EAAE;YAClC,SAAS,CAAC,qBAAqB,CAAC,8BAA8B,EAAE,CAAC,CAAC,CAAC;YACnE,CAAC,eAAe,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,iBAAiB,CAAC,QAAQ,EAAE;YAC5D,GAAG,KAAK,CAAC,IAAI,CAAC,oBAAoB,EAAE,SAAS,CAAC;SACjD,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACZ,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;YACpB,KAAK;YACL,gDAAgD;YAChD,UAAU,EAAE,YAAY;YACxB,WAAW,EAAE,aAAa;YAC1B,kBAAkB,EAAE,IAAI;SAC3B,CAAC,CAAC;IACP,CAAC;CACJ"}
@@ -0,0 +1,9 @@
1
+ import type { ScrcpyMediaStreamPacket } from "@yume-chan/scrcpy";
2
+ import type { CodecDecoder } from "./type.js";
3
+ export declare abstract class H26xDecoder implements CodecDecoder {
4
+ #private;
5
+ constructor(decoder: VideoDecoder);
6
+ abstract configure(data: Uint8Array): void;
7
+ decode(packet: ScrcpyMediaStreamPacket): void;
8
+ }
9
+ //# sourceMappingURL=h26x.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"h26x.d.ts","sourceRoot":"","sources":["../../../src/video/codec/h26x.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAEjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAE9C,8BAAsB,WAAY,YAAW,YAAY;;gBAIzC,OAAO,EAAE,YAAY;IAIjC,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI;IAE1C,MAAM,CAAC,MAAM,EAAE,uBAAuB,GAAG,IAAI;CA8BhD"}
@@ -0,0 +1,35 @@
1
+ export class H26xDecoder {
2
+ #config;
3
+ #decoder;
4
+ constructor(decoder) {
5
+ this.#decoder = decoder;
6
+ }
7
+ decode(packet) {
8
+ if (packet.type === "configuration") {
9
+ this.#config = packet.data;
10
+ this.configure(packet.data);
11
+ return;
12
+ }
13
+ // For H.264 and H.265, when the stream is in Annex B format
14
+ // (which Scrcpy uses, as Android MediaCodec produces),
15
+ // configuration data needs to be combined with the first frame data.
16
+ // https://www.w3.org/TR/webcodecs-avc-codec-registration/#encodedvideochunk-type
17
+ let data;
18
+ if (this.#config !== undefined) {
19
+ data = new Uint8Array(this.#config.length + packet.data.length);
20
+ data.set(this.#config, 0);
21
+ data.set(packet.data, this.#config.length);
22
+ this.#config = undefined;
23
+ }
24
+ else {
25
+ data = packet.data;
26
+ }
27
+ this.#decoder.decode(new EncodedVideoChunk({
28
+ // Treat `undefined` as `key`, otherwise won't decode.
29
+ type: packet.keyframe === false ? "delta" : "key",
30
+ timestamp: 0,
31
+ data,
32
+ }));
33
+ }
34
+ }
35
+ //# sourceMappingURL=h26x.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"h26x.js","sourceRoot":"","sources":["../../../src/video/codec/h26x.ts"],"names":[],"mappings":"AAIA,MAAM,OAAgB,WAAW;IAC7B,OAAO,CAAyB;IAChC,QAAQ,CAAe;IAEvB,YAAY,OAAqB;QAC7B,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;IAC5B,CAAC;IAID,MAAM,CAAC,MAA+B;QAClC,IAAI,MAAM,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;YAClC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC;YAC3B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC5B,OAAO;QACX,CAAC;QAED,4DAA4D;QAC5D,uDAAuD;QACvD,qEAAqE;QACrE,iFAAiF;QACjF,IAAI,IAAgB,CAAC;QACrB,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAC7B,IAAI,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAChE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YAC1B,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAC3C,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC;QAC7B,CAAC;aAAM,CAAC;YACJ,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;QACvB,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,MAAM,CAChB,IAAI,iBAAiB,CAAC;YAClB,sDAAsD;YACtD,IAAI,EAAE,MAAM,CAAC,QAAQ,KAAK,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK;YACjD,SAAS,EAAE,CAAC;YACZ,IAAI;SACP,CAAC,CACL,CAAC;IACN,CAAC;CACJ"}