1
1
import { useMemo , useState } from "react" ;
2
2
import { DebugFile } from "./DebugFile" ;
3
3
4
- const codec = "vp9" ;
5
-
6
4
export interface TestStreamProps {
7
5
stream : MediaStream ;
8
6
video : boolean ;
9
7
}
10
8
11
9
export const TestStream = ( { stream, video } : TestStreamProps ) => {
12
- const recorder = useMemo (
13
- ( ) =>
14
- new MediaRecorder ( stream , {
15
- mimeType : video ? "video/webm" + ( codec ? `;codecs=${ codec } ` : "" ) : "audio/webm" ,
10
+ const [ codecOption , setCodecOption ] = useState ( "" ) ;
11
+ const [ codecCustom , setCodecCustom ] = useState ( "" ) ;
12
+ const codec = codecOption === "custom" ? codecCustom : codecOption ;
13
+
14
+ const recorder = useMemo ( ( ) => {
15
+ try {
16
+ return new MediaRecorder ( stream , {
17
+ mimeType : ( video ? "video/webm" : "audio/webm" ) + ( codec ? `;codecs=${ codec } ` : "" ) ,
16
18
videoBitsPerSecond : 8000000 ,
17
- } ) ,
18
- [ stream , video ] ,
19
- ) ;
19
+ } ) ;
20
+ } catch ( error : unknown ) {
21
+ return error ;
22
+ }
23
+ } , [ stream , video , codec ] ) ;
20
24
21
25
const [ recording , setRecording ] = useState ( false ) ;
22
26
const [ duration , setDuration ] = useState ( 0 ) ;
23
27
const [ file , setFile ] = useState < Blob | null > ( null ) ;
24
28
25
29
const start = ( ) => {
30
+ if ( ! ( recorder instanceof MediaRecorder ) ) {
31
+ return ;
32
+ }
33
+
26
34
const parts : Blob [ ] = [ ] ;
27
35
const startTime = + new Date ( ) ;
28
36
const onData = ( { data } : BlobEvent ) => parts . push ( data ) ;
@@ -46,23 +54,57 @@ export const TestStream = ({ stream, video }: TestStreamProps) => {
46
54
47
55
return (
48
56
< div style = { { display : "flex" , flexDirection : "column" , gap : 20 } } >
49
- { ! recording && (
50
- < div >
51
- < button type = { "button" } onClick = { start } >
52
- Start
53
- </ button >
54
- </ div >
55
- ) }
57
+ < div >
58
+ < label >
59
+ Codec:
60
+ < select value = { codecOption } onChange = { ( ev ) => setCodecOption ( ev . target . value ) } >
61
+ < option value = { "" } > auto</ option >
62
+ { video && (
63
+ < >
64
+ < option value = { "vp8" } > vp8</ option >
65
+ < option value = { "vp9" } > vp9</ option >
66
+ </ >
67
+ ) }
68
+ < option value = { "custom" } > custom</ option >
69
+ </ select >
70
+ </ label >
56
71
57
- { recording && (
58
- < div >
59
- < button type = { "button" } onClick = { ( ) => recorder . stop ( ) } >
60
- Stop
61
- </ button >
62
- </ div >
63
- ) }
72
+ { codecOption === "custom" && (
73
+ < span >
74
+
75
+ < input
76
+ type = { "text" }
77
+ placeholder = { "Enter value..." }
78
+ value = { codecCustom }
79
+ onChange = { ( ev ) => setCodecCustom ( ev . target . value ) }
80
+ />
81
+ </ span >
82
+ ) }
83
+ </ div >
84
+
85
+ { ! ( recorder instanceof MediaRecorder ) && < div > { ( recorder as object ) . toString ( ) } </ div > }
86
+
87
+ { recorder instanceof MediaRecorder && (
88
+ < >
89
+ { ! recording && (
90
+ < div >
91
+ < button type = { "button" } onClick = { start } >
92
+ Start
93
+ </ button >
94
+ </ div >
95
+ ) }
64
96
65
- { ! recording && file && < DebugFile file = { file } duration = { duration } /> }
97
+ { recording && (
98
+ < div >
99
+ < button type = { "button" } onClick = { ( ) => recorder . stop ( ) } >
100
+ Stop
101
+ </ button >
102
+ </ div >
103
+ ) }
104
+
105
+ { ! recording && file && < DebugFile file = { file } duration = { duration } /> }
106
+ </ >
107
+ ) }
66
108
</ div >
67
109
) ;
68
110
} ;
0 commit comments