@streamplace/components 0.7.27 → 0.7.29
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.
- package/dist/components/chat/chat-box.js +2 -2
- package/dist/components/chat/chat.js +1 -1
- package/dist/components/mobile-player/ui/autoplay-button.js +1 -0
- package/dist/components/mobile-player/ui/viewer-context-menu.js +1 -1
- package/dist/components/mobile-player/ui/viewer-loading-overlay.js +2 -2
- package/dist/components/mobile-player/use-webrtc.js +30 -0
- package/dist/components/ui/button.js +107 -155
- package/dist/components/ui/dialog.js +83 -116
- package/dist/components/ui/dropdown.js +41 -18
- package/dist/components/ui/input.js +53 -128
- package/dist/components/ui/primitives/button.js +0 -2
- package/dist/components/ui/primitives/modal.js +2 -2
- package/dist/components/ui/primitives/text.js +48 -8
- package/dist/components/ui/text.js +37 -66
- package/dist/components/ui/toast.js +78 -40
- package/dist/components/ui/view.js +28 -41
- package/dist/lib/theme/index.js +1 -2
- package/dist/lib/theme/theme.js +106 -54
- package/dist/lib/theme/tokens.js +94 -1
- package/dist/ui/index.js +2 -3
- package/node-compile-cache/v22.15.0-x64-efe9a9df-0/37be0eec +0 -0
- package/package.json +3 -2
- package/src/components/chat/chat-box.tsx +6 -3
- package/src/components/chat/chat.tsx +1 -0
- package/src/components/mobile-player/ui/autoplay-button.tsx +1 -0
- package/src/components/mobile-player/ui/viewer-context-menu.tsx +2 -2
- package/src/components/mobile-player/ui/viewer-loading-overlay.tsx +2 -2
- package/src/components/mobile-player/use-webrtc.tsx +31 -0
- package/src/components/ui/button.tsx +110 -172
- package/src/components/ui/dialog.tsx +96 -138
- package/src/components/ui/dropdown.tsx +60 -22
- package/src/components/ui/input.tsx +57 -144
- package/src/components/ui/primitives/button.tsx +0 -2
- package/src/components/ui/primitives/modal.tsx +0 -2
- package/src/components/ui/primitives/text.tsx +51 -8
- package/src/components/ui/text.tsx +42 -67
- package/src/components/ui/toast.tsx +108 -90
- package/src/components/ui/view.tsx +27 -41
- package/src/lib/theme/index.ts +0 -2
- package/src/lib/theme/theme.tsx +179 -72
- package/src/lib/theme/tokens.ts +97 -0
- package/src/ui/index.ts +0 -2
- package/tsconfig.tsbuildinfo +1 -1
package/dist/lib/theme/tokens.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Inspired by shadcn/ui but adapted for React Native styling
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.breakpoints = exports.animations = exports.touchTargets = exports.shadows = exports.typography = exports.borderRadius = exports.spacing = exports.colors = void 0;
|
|
7
|
+
exports.breakpoints = exports.animations = exports.touchTargets = exports.shadows = exports.fontFamilies = exports.typography = exports.borderRadius = exports.spacing = exports.colors = void 0;
|
|
8
8
|
exports.colors = {
|
|
9
9
|
// Primary colors
|
|
10
10
|
primary: {
|
|
@@ -435,56 +435,67 @@ exports.typography = {
|
|
|
435
435
|
fontSize: 34,
|
|
436
436
|
lineHeight: 41,
|
|
437
437
|
fontWeight: "700",
|
|
438
|
+
fontFamily: "AtkinsonHyperlegibleNext-Bold",
|
|
438
439
|
},
|
|
439
440
|
title1: {
|
|
440
441
|
fontSize: 28,
|
|
441
442
|
lineHeight: 34,
|
|
442
443
|
fontWeight: "700",
|
|
444
|
+
fontFamily: "AtkinsonHyperlegibleNext-Bold",
|
|
443
445
|
},
|
|
444
446
|
title2: {
|
|
445
447
|
fontSize: 22,
|
|
446
448
|
lineHeight: 28,
|
|
447
449
|
fontWeight: "700",
|
|
450
|
+
fontFamily: "AtkinsonHyperlegibleNext-Bold",
|
|
448
451
|
},
|
|
449
452
|
title3: {
|
|
450
453
|
fontSize: 20,
|
|
451
454
|
lineHeight: 25,
|
|
452
455
|
fontWeight: "600",
|
|
456
|
+
fontFamily: "AtkinsonHyperlegibleNext-SemiBold",
|
|
453
457
|
},
|
|
454
458
|
headline: {
|
|
455
459
|
fontSize: 17,
|
|
456
460
|
lineHeight: 22,
|
|
457
461
|
fontWeight: "600",
|
|
462
|
+
fontFamily: "AtkinsonHyperlegibleNext-SemiBold",
|
|
458
463
|
},
|
|
459
464
|
body: {
|
|
460
465
|
fontSize: 17,
|
|
461
466
|
lineHeight: 22,
|
|
462
467
|
fontWeight: "400",
|
|
468
|
+
fontFamily: "AtkinsonHyperlegibleNext-Regular",
|
|
463
469
|
},
|
|
464
470
|
callout: {
|
|
465
471
|
fontSize: 16,
|
|
466
472
|
lineHeight: 21,
|
|
467
473
|
fontWeight: "400",
|
|
474
|
+
fontFamily: "AtkinsonHyperlegibleNext-Regular",
|
|
468
475
|
},
|
|
469
476
|
subhead: {
|
|
470
477
|
fontSize: 15,
|
|
471
478
|
lineHeight: 20,
|
|
472
479
|
fontWeight: "400",
|
|
480
|
+
fontFamily: "AtkinsonHyperlegibleNext-Regular",
|
|
473
481
|
},
|
|
474
482
|
footnote: {
|
|
475
483
|
fontSize: 13,
|
|
476
484
|
lineHeight: 18,
|
|
477
485
|
fontWeight: "400",
|
|
486
|
+
fontFamily: "AtkinsonHyperlegibleNext-Regular",
|
|
478
487
|
},
|
|
479
488
|
caption1: {
|
|
480
489
|
fontSize: 12,
|
|
481
490
|
lineHeight: 16,
|
|
482
491
|
fontWeight: "400",
|
|
492
|
+
fontFamily: "AtkinsonHyperlegibleNext-Regular",
|
|
483
493
|
},
|
|
484
494
|
caption2: {
|
|
485
495
|
fontSize: 11,
|
|
486
496
|
lineHeight: 13,
|
|
487
497
|
fontWeight: "400",
|
|
498
|
+
fontFamily: "AtkinsonHyperlegibleNext-Regular",
|
|
488
499
|
},
|
|
489
500
|
},
|
|
490
501
|
// Android Material typography
|
|
@@ -493,66 +504,79 @@ exports.typography = {
|
|
|
493
504
|
fontSize: 96,
|
|
494
505
|
lineHeight: 112,
|
|
495
506
|
fontWeight: "300",
|
|
507
|
+
fontFamily: "AtkinsonHyperlegibleNext-ExtraLight",
|
|
496
508
|
},
|
|
497
509
|
headline2: {
|
|
498
510
|
fontSize: 60,
|
|
499
511
|
lineHeight: 72,
|
|
500
512
|
fontWeight: "300",
|
|
513
|
+
fontFamily: "AtkinsonHyperlegibleNext-Light",
|
|
501
514
|
},
|
|
502
515
|
headline3: {
|
|
503
516
|
fontSize: 48,
|
|
504
517
|
lineHeight: 56,
|
|
505
518
|
fontWeight: "400",
|
|
519
|
+
fontFamily: "AtkinsonHyperlegibleNext-Regular",
|
|
506
520
|
},
|
|
507
521
|
headline4: {
|
|
508
522
|
fontSize: 34,
|
|
509
523
|
lineHeight: 42,
|
|
510
524
|
fontWeight: "400",
|
|
525
|
+
fontFamily: "AtkinsonHyperlegibleNext-Regular",
|
|
511
526
|
},
|
|
512
527
|
headline5: {
|
|
513
528
|
fontSize: 24,
|
|
514
529
|
lineHeight: 32,
|
|
515
530
|
fontWeight: "400",
|
|
531
|
+
fontFamily: "AtkinsonHyperlegibleNext-Regular",
|
|
516
532
|
},
|
|
517
533
|
headline6: {
|
|
518
534
|
fontSize: 20,
|
|
519
535
|
lineHeight: 28,
|
|
520
536
|
fontWeight: "500",
|
|
537
|
+
fontFamily: "AtkinsonHyperlegibleNext-Medium",
|
|
521
538
|
},
|
|
522
539
|
subtitle1: {
|
|
523
540
|
fontSize: 16,
|
|
524
541
|
lineHeight: 24,
|
|
525
542
|
fontWeight: "400",
|
|
543
|
+
fontFamily: "AtkinsonHyperlegibleNext-Regular",
|
|
526
544
|
},
|
|
527
545
|
subtitle2: {
|
|
528
546
|
fontSize: 14,
|
|
529
547
|
lineHeight: 22,
|
|
530
548
|
fontWeight: "500",
|
|
549
|
+
fontFamily: "AtkinsonHyperlegibleNext-Medium",
|
|
531
550
|
},
|
|
532
551
|
body1: {
|
|
533
552
|
fontSize: 16,
|
|
534
553
|
lineHeight: 24,
|
|
535
554
|
fontWeight: "400",
|
|
555
|
+
fontFamily: "AtkinsonHyperlegibleNext-Regular",
|
|
536
556
|
},
|
|
537
557
|
body2: {
|
|
538
558
|
fontSize: 14,
|
|
539
559
|
lineHeight: 20,
|
|
540
560
|
fontWeight: "400",
|
|
561
|
+
fontFamily: "AtkinsonHyperlegibleNext-Regular",
|
|
541
562
|
},
|
|
542
563
|
button: {
|
|
543
564
|
fontSize: 14,
|
|
544
565
|
lineHeight: 16,
|
|
545
566
|
fontWeight: "500",
|
|
567
|
+
fontFamily: "AtkinsonHyperlegibleNext-Medium",
|
|
546
568
|
},
|
|
547
569
|
caption: {
|
|
548
570
|
fontSize: 12,
|
|
549
571
|
lineHeight: 16,
|
|
550
572
|
fontWeight: "400",
|
|
573
|
+
fontFamily: "AtkinsonHyperlegibleNext-Regular",
|
|
551
574
|
},
|
|
552
575
|
overline: {
|
|
553
576
|
fontSize: 10,
|
|
554
577
|
lineHeight: 16,
|
|
555
578
|
fontWeight: "400",
|
|
579
|
+
fontFamily: "AtkinsonHyperlegibleNext-Regular",
|
|
556
580
|
},
|
|
557
581
|
},
|
|
558
582
|
// Universal typography scale
|
|
@@ -561,43 +585,112 @@ exports.typography = {
|
|
|
561
585
|
fontSize: 12,
|
|
562
586
|
lineHeight: 16,
|
|
563
587
|
fontWeight: "400",
|
|
588
|
+
fontFamily: "AtkinsonHyperlegibleNext-Regular",
|
|
564
589
|
},
|
|
565
590
|
sm: {
|
|
566
591
|
fontSize: 14,
|
|
567
592
|
lineHeight: 20,
|
|
568
593
|
fontWeight: "400",
|
|
594
|
+
fontFamily: "AtkinsonHyperlegibleNext-Regular",
|
|
569
595
|
},
|
|
570
596
|
base: {
|
|
571
597
|
fontSize: 16,
|
|
572
598
|
lineHeight: 24,
|
|
573
599
|
fontWeight: "400",
|
|
600
|
+
fontFamily: "AtkinsonHyperlegibleNext-Regular",
|
|
574
601
|
},
|
|
575
602
|
lg: {
|
|
576
603
|
fontSize: 18,
|
|
577
604
|
lineHeight: 28,
|
|
578
605
|
fontWeight: "400",
|
|
606
|
+
fontFamily: "AtkinsonHyperlegibleNext-Regular",
|
|
579
607
|
},
|
|
580
608
|
xl: {
|
|
581
609
|
fontSize: 20,
|
|
582
610
|
lineHeight: 28,
|
|
583
611
|
fontWeight: "500",
|
|
612
|
+
fontFamily: "AtkinsonHyperlegibleNext-Medium",
|
|
584
613
|
},
|
|
585
614
|
"2xl": {
|
|
586
615
|
fontSize: 24,
|
|
587
616
|
lineHeight: 32,
|
|
588
617
|
fontWeight: "600",
|
|
618
|
+
fontFamily: "AtkinsonHyperlegibleNext-SemiBold",
|
|
589
619
|
},
|
|
590
620
|
"3xl": {
|
|
591
621
|
fontSize: 30,
|
|
592
622
|
lineHeight: 36,
|
|
593
623
|
fontWeight: "700",
|
|
624
|
+
fontFamily: "AtkinsonHyperlegibleNext-Bold",
|
|
594
625
|
},
|
|
595
626
|
"4xl": {
|
|
596
627
|
fontSize: 36,
|
|
597
628
|
lineHeight: 40,
|
|
598
629
|
fontWeight: "700",
|
|
630
|
+
fontFamily: "AtkinsonHyperlegibleNext-ExtraBold",
|
|
599
631
|
},
|
|
600
632
|
},
|
|
633
|
+
// Monospace typography for code and technical content
|
|
634
|
+
mono: {
|
|
635
|
+
xs: {
|
|
636
|
+
fontSize: 11,
|
|
637
|
+
lineHeight: 16,
|
|
638
|
+
fontWeight: "400",
|
|
639
|
+
fontFamily: "AtkinsonHyperlegibleMono-Regular",
|
|
640
|
+
},
|
|
641
|
+
sm: {
|
|
642
|
+
fontSize: 13,
|
|
643
|
+
lineHeight: 18,
|
|
644
|
+
fontWeight: "400",
|
|
645
|
+
fontFamily: "AtkinsonHyperlegibleMono-Regular",
|
|
646
|
+
},
|
|
647
|
+
base: {
|
|
648
|
+
fontSize: 14,
|
|
649
|
+
lineHeight: 20,
|
|
650
|
+
fontWeight: "400",
|
|
651
|
+
fontFamily: "AtkinsonHyperlegibleMono-Regular",
|
|
652
|
+
},
|
|
653
|
+
lg: {
|
|
654
|
+
fontSize: 16,
|
|
655
|
+
lineHeight: 24,
|
|
656
|
+
fontWeight: "400",
|
|
657
|
+
fontFamily: "AtkinsonHyperlegibleMono-Regular",
|
|
658
|
+
},
|
|
659
|
+
xl: {
|
|
660
|
+
fontSize: 18,
|
|
661
|
+
lineHeight: 28,
|
|
662
|
+
fontWeight: "500",
|
|
663
|
+
fontFamily: "AtkinsonHyperlegibleMono-Medium",
|
|
664
|
+
},
|
|
665
|
+
"2xl": {
|
|
666
|
+
fontSize: 20,
|
|
667
|
+
lineHeight: 32,
|
|
668
|
+
fontWeight: "600",
|
|
669
|
+
fontFamily: "AtkinsonHyperlegibleMono-SemiBold",
|
|
670
|
+
},
|
|
671
|
+
"3xl": {
|
|
672
|
+
fontSize: 24,
|
|
673
|
+
lineHeight: 36,
|
|
674
|
+
fontWeight: "700",
|
|
675
|
+
fontFamily: "AtkinsonHyperlegibleMono-Bold",
|
|
676
|
+
},
|
|
677
|
+
},
|
|
678
|
+
};
|
|
679
|
+
// Font families available in the app
|
|
680
|
+
exports.fontFamilies = {
|
|
681
|
+
// Sans serif fonts
|
|
682
|
+
regular: "AtkinsonHyperlegibleNext-Regular",
|
|
683
|
+
light: "AtkinsonHyperlegibleNext-Light",
|
|
684
|
+
extraLight: "AtkinsonHyperlegibleNext-ExtraLight",
|
|
685
|
+
medium: "AtkinsonHyperlegibleNext-Medium",
|
|
686
|
+
semiBold: "AtkinsonHyperlegibleNext-SemiBold",
|
|
687
|
+
bold: "AtkinsonHyperlegibleNext-Bold",
|
|
688
|
+
extraBold: "AtkinsonHyperlegibleNext-ExtraBold",
|
|
689
|
+
// Monospace fonts
|
|
690
|
+
monoRegular: "AtkinsonHyperlegibleMono-Regular",
|
|
691
|
+
monoMedium: "AtkinsonHyperlegibleMono-Medium",
|
|
692
|
+
monoSemiBold: "AtkinsonHyperlegibleMono-SemiBold",
|
|
693
|
+
monoBold: "AtkinsonHyperlegibleMono-Bold",
|
|
601
694
|
};
|
|
602
695
|
exports.shadows = {
|
|
603
696
|
none: {
|
package/dist/ui/index.js
CHANGED
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
* ZeroCSS provides a zero-config, atomic styling system optimized for React Native.
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.atomsNS = exports.theme = exports.useTheme = exports.usePlatformTypography = exports.lightTheme = exports.darkTheme = exports.createThemedStyles = exports.
|
|
10
|
-
exports.utils =
|
|
9
|
+
exports.tokens = exports.atomsNS = exports.theme = exports.useTheme = exports.usePlatformTypography = exports.lightTheme = exports.darkTheme = exports.createThemedStyles = exports.createThemeIcons = exports.createThemeColors = exports.ThemeProvider = exports.responsiveValue = exports.platformStyle = exports.mergeStyles = exports.debounce = exports.typography = exports.spacing = exports.shadows = exports.colors = exports.breakpoints = exports.borderRadius = exports.w = exports.top = exports.text = exports.right = exports.r = exports.py = exports.px = exports.pt = exports.pr = exports.position = exports.pl = exports.pb = exports.p = exports.my = exports.mx = exports.mt = exports.mr = exports.ml = exports.mb = exports.m = exports.left = exports.layout = exports.h = exports.gap = exports.flex = exports.bottom = exports.borders = exports.bg = exports.atoms = void 0;
|
|
10
|
+
exports.utils = void 0;
|
|
11
11
|
const tslib_1 = require("tslib");
|
|
12
12
|
// Export the most commonly used ZeroCSS utilities
|
|
13
13
|
var atoms_1 = require("../lib/theme/atoms");
|
|
@@ -66,7 +66,6 @@ var theme_1 = require("../lib/theme/theme");
|
|
|
66
66
|
Object.defineProperty(exports, "ThemeProvider", { enumerable: true, get: function () { return theme_1.ThemeProvider; } });
|
|
67
67
|
Object.defineProperty(exports, "createThemeColors", { enumerable: true, get: function () { return theme_1.createThemeColors; } });
|
|
68
68
|
Object.defineProperty(exports, "createThemeIcons", { enumerable: true, get: function () { return theme_1.createThemeIcons; } });
|
|
69
|
-
Object.defineProperty(exports, "createThemeStyles", { enumerable: true, get: function () { return theme_1.createThemeStyles; } });
|
|
70
69
|
Object.defineProperty(exports, "createThemedStyles", { enumerable: true, get: function () { return theme_1.createThemedStyles; } });
|
|
71
70
|
Object.defineProperty(exports, "darkTheme", { enumerable: true, get: function () { return theme_1.darkTheme; } });
|
|
72
71
|
Object.defineProperty(exports, "lightTheme", { enumerable: true, get: function () { return theme_1.lightTheme; } });
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@streamplace/components",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.29",
|
|
4
4
|
"description": "Streamplace React (Native) Components",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "src/index.tsx",
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
"author": "Streamplace",
|
|
18
18
|
"license": "MIT",
|
|
19
19
|
"devDependencies": {
|
|
20
|
+
"@types/sdp-transform": "^2.15.0",
|
|
20
21
|
"tsup": "^8.5.0"
|
|
21
22
|
},
|
|
22
23
|
"dependencies": {
|
|
@@ -53,5 +54,5 @@
|
|
|
53
54
|
"start": "tsc --watch --preserveWatchOutput",
|
|
54
55
|
"prepare": "tsc"
|
|
55
56
|
},
|
|
56
|
-
"gitHead": "
|
|
57
|
+
"gitHead": "8dba54b751a4a48f125485ef8b0997428f6095cf"
|
|
57
58
|
}
|
|
@@ -421,7 +421,8 @@ export function ChatBox({
|
|
|
421
421
|
>
|
|
422
422
|
<Button
|
|
423
423
|
variant="secondary"
|
|
424
|
-
style={{ borderRadius: 16,
|
|
424
|
+
style={{ borderRadius: 16, maxWidth: 44, aspectRatio: 1 }}
|
|
425
|
+
aria-label="Insert Mention"
|
|
425
426
|
onPress={() => {
|
|
426
427
|
// if the last character is not @, add it
|
|
427
428
|
!message.endsWith("@") && setMessage(message + "@");
|
|
@@ -445,7 +446,8 @@ export function ChatBox({
|
|
|
445
446
|
>
|
|
446
447
|
<Button
|
|
447
448
|
variant="secondary"
|
|
448
|
-
|
|
449
|
+
aria-label="Insert Emoji"
|
|
450
|
+
style={{ borderRadius: 16, maxWidth: 44, aspectRatio: 1 }}
|
|
449
451
|
onPress={() => setShowEmojiSelector(!showEmojiSelector)}
|
|
450
452
|
>
|
|
451
453
|
<Text>{COOL_EMOJI_LIST[emojiIconIndex]}</Text>
|
|
@@ -454,7 +456,8 @@ export function ChatBox({
|
|
|
454
456
|
{!isPopout && (
|
|
455
457
|
<Button
|
|
456
458
|
variant="secondary"
|
|
457
|
-
|
|
459
|
+
aria-label="Popout Chat"
|
|
460
|
+
style={{ borderRadius: 16, maxWidth: 44, aspectRatio: 1 }}
|
|
458
461
|
onPress={() => {
|
|
459
462
|
if (!linfo) return;
|
|
460
463
|
const u = new URL(window.location.href);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useRootContext } from "@rn-primitives/dropdown-menu";
|
|
2
|
-
import {
|
|
2
|
+
import { Menu } from "lucide-react-native";
|
|
3
3
|
import { Platform, View } from "react-native";
|
|
4
4
|
import { colors } from "../../../lib/theme";
|
|
5
5
|
import { useLivestreamStore } from "../../../livestream-store";
|
|
@@ -57,7 +57,7 @@ export function ContextMenu({
|
|
|
57
57
|
return (
|
|
58
58
|
<DropdownMenu>
|
|
59
59
|
<DropdownMenuTrigger>
|
|
60
|
-
<
|
|
60
|
+
<Menu color={colors.gray[200]} />
|
|
61
61
|
</DropdownMenuTrigger>
|
|
62
62
|
<Portal container={dropdownPortalContainer}>
|
|
63
63
|
<DropdownMenuContent side="top" align="end">
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
|
|
16
16
|
export function ViewerLoadingOverlay() {
|
|
17
17
|
const status = usePlayerStore((x) => x.status);
|
|
18
|
-
const theme = useTheme();
|
|
18
|
+
const { theme, zero: zt } = useTheme();
|
|
19
19
|
const opacity = useSharedValue(0);
|
|
20
20
|
|
|
21
21
|
useEffect(() => {
|
|
@@ -42,7 +42,7 @@ export function ViewerLoadingOverlay() {
|
|
|
42
42
|
|
|
43
43
|
let spinner = <Loader size="large" />;
|
|
44
44
|
if (status === PlayerStatus.PAUSE) {
|
|
45
|
-
spinner = <Play size="$12" color={theme.
|
|
45
|
+
spinner = <Play size="$12" color={theme.colors.foreground} />;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
return (
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useEffect, useRef, useState } from "react";
|
|
2
|
+
import * as sdpTransform from "sdp-transform";
|
|
2
3
|
import { PlayerStatus, usePlayerStore, useStreamKey } from "../..";
|
|
3
4
|
import { RTCPeerConnection, RTCSessionDescription } from "./webrtc-primitives";
|
|
4
5
|
|
|
@@ -107,6 +108,13 @@ export async function negotiateConnectionWithClientOffer(
|
|
|
107
108
|
offerToReceiveAudio: true,
|
|
108
109
|
offerToReceiveVideo: true,
|
|
109
110
|
});
|
|
111
|
+
if (!offer.sdp) {
|
|
112
|
+
throw Error("no SDP in offer");
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const newSDP = forceStereoAudio(offer.sdp);
|
|
116
|
+
|
|
117
|
+
offer.sdp = newSDP;
|
|
110
118
|
/** https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/setLocalDescription */
|
|
111
119
|
await peerConnection.setLocalDescription(offer);
|
|
112
120
|
|
|
@@ -297,3 +305,26 @@ export function useWebRTCIngest({
|
|
|
297
305
|
|
|
298
306
|
return [mediaStream, setMediaStream];
|
|
299
307
|
}
|
|
308
|
+
|
|
309
|
+
export function forceStereoAudio(sdp: string): string {
|
|
310
|
+
const parsedSDP = sdpTransform.parse(sdp);
|
|
311
|
+
const audioMedia = parsedSDP.media.find((m) => m.type === "audio");
|
|
312
|
+
if (!audioMedia) {
|
|
313
|
+
throw Error("no audio media in SDP");
|
|
314
|
+
}
|
|
315
|
+
const opusCodec = audioMedia.rtp.find((c) => c.codec === "opus");
|
|
316
|
+
if (!opusCodec) {
|
|
317
|
+
throw Error("no opus codec in SDP");
|
|
318
|
+
}
|
|
319
|
+
const opusFMTP = audioMedia.fmtp.find((c) => c.payload === opusCodec.payload);
|
|
320
|
+
if (!opusFMTP) {
|
|
321
|
+
throw Error("no opus fmtp in SDP");
|
|
322
|
+
}
|
|
323
|
+
const opusParams = sdpTransform.parseParams(opusFMTP.config);
|
|
324
|
+
opusParams.stereo = 1;
|
|
325
|
+
const newParams = Object.entries(opusParams)
|
|
326
|
+
.map(([k, v]) => `${k}=${v}`)
|
|
327
|
+
.join(";");
|
|
328
|
+
opusFMTP.config = newParams;
|
|
329
|
+
return sdpTransform.write(parsedSDP);
|
|
330
|
+
}
|