agora-electron-sdk 4.2.6 → 4.3.0-dev.1

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 (172) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/js/Private/AgoraBase.js +139 -174
  3. package/js/Private/AgoraMediaBase.js +49 -20
  4. package/js/Private/AgoraMediaPlayerTypes.js +32 -23
  5. package/js/Private/IAgoraH265Transcoder.js +39 -0
  6. package/js/Private/IAgoraMediaStreamingSource.js +32 -32
  7. package/js/Private/IAgoraMusicContentCenter.js +19 -19
  8. package/js/Private/IAgoraRhythmPlayer.js +9 -9
  9. package/js/Private/IAgoraRtcEngine.js +12 -12
  10. package/js/Private/IAgoraSpatialAudio.js +3 -31
  11. package/js/Private/extension/IAgoraH265TranscoderExtension.js +2 -0
  12. package/js/Private/impl/AgoraMediaBaseImpl.js +26 -2
  13. package/js/Private/impl/IAgoraH265TranscoderImpl.js +119 -0
  14. package/js/Private/impl/IAgoraMediaEngineImpl.js +13 -13
  15. package/js/Private/impl/IAgoraMediaPlayerImpl.js +92 -74
  16. package/js/Private/impl/IAgoraMediaPlayerSourceImpl.js +12 -2
  17. package/js/Private/impl/IAgoraMediaRecorderImpl.js +2 -2
  18. package/js/Private/impl/IAgoraMusicContentCenterImpl.js +20 -20
  19. package/js/Private/impl/IAgoraRtcEngineExImpl.js +66 -84
  20. package/js/Private/impl/IAgoraRtcEngineImpl.js +456 -440
  21. package/js/Private/impl/IAgoraSpatialAudioImpl.js +157 -181
  22. package/js/Private/impl/IAudioDeviceManagerImpl.js +22 -22
  23. package/js/Private/internal/AgoraH265TranscoderInternal.js +86 -0
  24. package/js/Private/internal/AgoraMediaBaseInternal.js +34 -0
  25. package/js/Private/internal/IrisApiEngine.js +35 -20
  26. package/js/Private/internal/LocalSpatialAudioEngineInternal.js +0 -39
  27. package/js/Private/internal/MediaPlayerInternal.js +22 -21
  28. package/js/Private/internal/MusicContentCenterInternal.js +1 -4
  29. package/js/Private/internal/RtcEngineExInternal.js +101 -134
  30. package/js/Private/ti/AgoraMediaBase-ti.js +1 -1
  31. package/js/Private/ti/IAgoraH265Transcoder-ti.js +40 -0
  32. package/js/Private/ti/IAgoraMediaPlayerSource-ti.js +4 -2
  33. package/js/Private/ti/IAgoraMusicContentCenter-ti.js +5 -5
  34. package/js/Private/ti/IAgoraRtcEngine-ti.js +12 -11
  35. package/js/Renderer/AgoraView.js +28 -14
  36. package/js/Renderer/IRenderer.js +65 -17
  37. package/js/Renderer/IRendererManager.js +230 -0
  38. package/js/Renderer/RendererCache.js +170 -0
  39. package/js/Renderer/RendererManager.js +49 -460
  40. package/js/Renderer/WebGLRenderer/index.js +82 -234
  41. package/js/Renderer/YUVCanvasRenderer/index.js +27 -147
  42. package/js/Types.js +6 -6
  43. package/js/Utils.js +37 -88
  44. package/package.json +4 -3
  45. package/scripts/clean.js +12 -0
  46. package/scripts/synclib.js +8 -2
  47. package/ts/Private/AgoraBase.ts +225 -201
  48. package/ts/Private/AgoraMediaBase.ts +63 -25
  49. package/ts/Private/AgoraMediaPlayerTypes.ts +67 -24
  50. package/ts/Private/IAgoraH265Transcoder.ts +73 -0
  51. package/ts/Private/IAgoraLog.ts +1 -0
  52. package/ts/Private/IAgoraMediaEngine.ts +12 -7
  53. package/ts/Private/IAgoraMediaPlayer.ts +47 -21
  54. package/ts/Private/IAgoraMediaPlayerSource.ts +27 -6
  55. package/ts/Private/IAgoraMediaStreamingSource.ts +38 -37
  56. package/ts/Private/IAgoraMusicContentCenter.ts +20 -20
  57. package/ts/Private/IAgoraRhythmPlayer.ts +7 -6
  58. package/ts/Private/IAgoraRtcEngine.ts +407 -364
  59. package/ts/Private/IAgoraRtcEngineEx.ts +25 -61
  60. package/ts/Private/IAgoraSpatialAudio.ts +80 -191
  61. package/ts/Private/IAudioDeviceManager.ts +27 -14
  62. package/ts/Private/extension/IAgoraH265TranscoderExtension.ts +39 -0
  63. package/ts/Private/impl/AgoraMediaBaseImpl.ts +25 -1
  64. package/ts/Private/impl/IAgoraH265TranscoderImpl.ts +152 -0
  65. package/ts/Private/impl/IAgoraMediaEngineImpl.ts +13 -13
  66. package/ts/Private/impl/IAgoraMediaPlayerImpl.ts +110 -81
  67. package/ts/Private/impl/IAgoraMediaPlayerSourceImpl.ts +17 -2
  68. package/ts/Private/impl/IAgoraMediaRecorderImpl.ts +2 -2
  69. package/ts/Private/impl/IAgoraMusicContentCenterImpl.ts +21 -21
  70. package/ts/Private/impl/IAgoraRtcEngineExImpl.ts +71 -106
  71. package/ts/Private/impl/IAgoraRtcEngineImpl.ts +589 -572
  72. package/ts/Private/impl/IAgoraSpatialAudioImpl.ts +211 -218
  73. package/ts/Private/impl/IAudioDeviceManagerImpl.ts +22 -22
  74. package/ts/Private/internal/AgoraH265TranscoderInternal.ts +97 -0
  75. package/ts/Private/internal/AgoraMediaBaseInternal.ts +15 -0
  76. package/ts/Private/internal/IrisApiEngine.ts +42 -27
  77. package/ts/Private/internal/LocalSpatialAudioEngineInternal.ts +1 -86
  78. package/ts/Private/internal/MediaPlayerInternal.ts +20 -29
  79. package/ts/Private/internal/MusicContentCenterInternal.ts +1 -5
  80. package/ts/Private/internal/RtcEngineExInternal.ts +91 -204
  81. package/ts/Private/ti/AgoraMediaBase-ti.ts +1 -1
  82. package/ts/Private/ti/IAgoraH265Transcoder-ti.ts +16 -0
  83. package/ts/Private/ti/IAgoraMediaPlayerSource-ti.ts +4 -2
  84. package/ts/Private/ti/IAgoraMusicContentCenter-ti.ts +5 -5
  85. package/ts/Private/ti/IAgoraRtcEngine-ti.ts +12 -11
  86. package/ts/Renderer/AgoraView.ts +29 -19
  87. package/ts/Renderer/IRenderer.ts +71 -22
  88. package/ts/Renderer/IRendererManager.ts +273 -19
  89. package/ts/Renderer/RendererCache.ts +167 -0
  90. package/ts/Renderer/RendererManager.ts +62 -607
  91. package/ts/Renderer/WebGLRenderer/index.ts +117 -295
  92. package/ts/Renderer/YUVCanvasRenderer/index.ts +45 -198
  93. package/ts/Types.ts +17 -194
  94. package/ts/Utils.ts +36 -100
  95. package/types/Private/AgoraBase.d.ts +219 -200
  96. package/types/Private/AgoraBase.d.ts.map +1 -1
  97. package/types/Private/AgoraMediaBase.d.ts +63 -27
  98. package/types/Private/AgoraMediaBase.d.ts.map +1 -1
  99. package/types/Private/AgoraMediaPlayerTypes.d.ts +65 -24
  100. package/types/Private/AgoraMediaPlayerTypes.d.ts.map +1 -1
  101. package/types/Private/IAgoraH265Transcoder.d.ts +28 -0
  102. package/types/Private/IAgoraH265Transcoder.d.ts.map +1 -0
  103. package/types/Private/IAgoraLog.d.ts.map +1 -1
  104. package/types/Private/IAgoraMediaEngine.d.ts +11 -6
  105. package/types/Private/IAgoraMediaEngine.d.ts.map +1 -1
  106. package/types/Private/IAgoraMediaPlayer.d.ts +42 -20
  107. package/types/Private/IAgoraMediaPlayer.d.ts.map +1 -1
  108. package/types/Private/IAgoraMediaPlayerSource.d.ts +23 -6
  109. package/types/Private/IAgoraMediaPlayerSource.d.ts.map +1 -1
  110. package/types/Private/IAgoraMediaStreamingSource.d.ts.map +1 -1
  111. package/types/Private/IAgoraMusicContentCenter.d.ts +19 -19
  112. package/types/Private/IAgoraMusicContentCenter.d.ts.map +1 -1
  113. package/types/Private/IAgoraRhythmPlayer.d.ts +6 -6
  114. package/types/Private/IAgoraRhythmPlayer.d.ts.map +1 -1
  115. package/types/Private/IAgoraRtcEngine.d.ts +329 -293
  116. package/types/Private/IAgoraRtcEngine.d.ts.map +1 -1
  117. package/types/Private/IAgoraRtcEngineEx.d.ts +21 -53
  118. package/types/Private/IAgoraRtcEngineEx.d.ts.map +1 -1
  119. package/types/Private/IAgoraSpatialAudio.d.ts +56 -167
  120. package/types/Private/IAgoraSpatialAudio.d.ts.map +1 -1
  121. package/types/Private/IAudioDeviceManager.d.ts +27 -14
  122. package/types/Private/IAudioDeviceManager.d.ts.map +1 -1
  123. package/types/Private/extension/IAgoraH265TranscoderExtension.d.ts +24 -0
  124. package/types/Private/extension/IAgoraH265TranscoderExtension.d.ts.map +1 -0
  125. package/types/Private/impl/AgoraMediaBaseImpl.d.ts +5 -1
  126. package/types/Private/impl/AgoraMediaBaseImpl.d.ts.map +1 -1
  127. package/types/Private/impl/IAgoraH265TranscoderImpl.d.ts +15 -0
  128. package/types/Private/impl/IAgoraH265TranscoderImpl.d.ts.map +1 -0
  129. package/types/Private/impl/IAgoraMediaPlayerImpl.d.ts +6 -4
  130. package/types/Private/impl/IAgoraMediaPlayerImpl.d.ts.map +1 -1
  131. package/types/Private/impl/IAgoraMediaPlayerSourceImpl.d.ts.map +1 -1
  132. package/types/Private/impl/IAgoraRtcEngineExImpl.d.ts +2 -4
  133. package/types/Private/impl/IAgoraRtcEngineExImpl.d.ts.map +1 -1
  134. package/types/Private/impl/IAgoraRtcEngineImpl.d.ts +30 -25
  135. package/types/Private/impl/IAgoraRtcEngineImpl.d.ts.map +1 -1
  136. package/types/Private/impl/IAgoraSpatialAudioImpl.d.ts +20 -22
  137. package/types/Private/impl/IAgoraSpatialAudioImpl.d.ts.map +1 -1
  138. package/types/Private/internal/AgoraH265TranscoderInternal.d.ts +14 -0
  139. package/types/Private/internal/AgoraH265TranscoderInternal.d.ts.map +1 -0
  140. package/types/Private/internal/AgoraMediaBaseInternal.d.ts +8 -0
  141. package/types/Private/internal/AgoraMediaBaseInternal.d.ts.map +1 -0
  142. package/types/Private/internal/IrisApiEngine.d.ts +5 -2
  143. package/types/Private/internal/IrisApiEngine.d.ts.map +1 -1
  144. package/types/Private/internal/LocalSpatialAudioEngineInternal.d.ts +0 -15
  145. package/types/Private/internal/LocalSpatialAudioEngineInternal.d.ts.map +1 -1
  146. package/types/Private/internal/MediaPlayerInternal.d.ts.map +1 -1
  147. package/types/Private/internal/MusicContentCenterInternal.d.ts +0 -1
  148. package/types/Private/internal/MusicContentCenterInternal.d.ts.map +1 -1
  149. package/types/Private/internal/RtcEngineExInternal.d.ts +7 -13
  150. package/types/Private/internal/RtcEngineExInternal.d.ts.map +1 -1
  151. package/types/Private/ti/IAgoraH265Transcoder-ti.d.ts +8 -0
  152. package/types/Private/ti/IAgoraH265Transcoder-ti.d.ts.map +1 -0
  153. package/types/Private/ti/IAgoraMediaPlayerSource-ti.d.ts.map +1 -1
  154. package/types/Private/ti/IAgoraRtcEngine-ti.d.ts.map +1 -1
  155. package/types/Renderer/AgoraView.d.ts +4 -4
  156. package/types/Renderer/AgoraView.d.ts.map +1 -1
  157. package/types/Renderer/IRenderer.d.ts +11 -9
  158. package/types/Renderer/IRenderer.d.ts.map +1 -1
  159. package/types/Renderer/IRendererManager.d.ts +50 -12
  160. package/types/Renderer/IRendererManager.d.ts.map +1 -1
  161. package/types/Renderer/RendererCache.d.ts +36 -0
  162. package/types/Renderer/RendererCache.d.ts.map +1 -0
  163. package/types/Renderer/RendererManager.d.ts +13 -139
  164. package/types/Renderer/RendererManager.d.ts.map +1 -1
  165. package/types/Renderer/WebGLRenderer/index.d.ts +3 -18
  166. package/types/Renderer/WebGLRenderer/index.d.ts.map +1 -1
  167. package/types/Renderer/YUVCanvasRenderer/index.d.ts +4 -10
  168. package/types/Renderer/YUVCanvasRenderer/index.d.ts.map +1 -1
  169. package/types/Types.d.ts +11 -187
  170. package/types/Types.d.ts.map +1 -1
  171. package/types/Utils.d.ts +3 -20
  172. package/types/Utils.d.ts.map +1 -1
@@ -28,7 +28,7 @@ export const IRtcEngineEventHandler = t.iface([], {
28
28
  "onFirstLocalVideoFramePublished": t.opt(t.func("void", t.param("source", "VideoSourceType"), t.param("elapsed", "number"))),
29
29
  "onFirstRemoteVideoDecoded": t.opt(t.func("void", t.param("connection", "RtcConnection"), t.param("remoteUid", "number"), t.param("width", "number"), t.param("height", "number"), t.param("elapsed", "number"))),
30
30
  "onVideoSizeChanged": t.opt(t.func("void", t.param("connection", "RtcConnection"), t.param("sourceType", "VideoSourceType"), t.param("uid", "number"), t.param("width", "number"), t.param("height", "number"), t.param("rotation", "number"))),
31
- "onLocalVideoStateChanged": t.opt(t.func("void", t.param("source", "VideoSourceType"), t.param("state", "LocalVideoStreamState"), t.param("error", "LocalVideoStreamError"))),
31
+ "onLocalVideoStateChanged": t.opt(t.func("void", t.param("source", "VideoSourceType"), t.param("state", "LocalVideoStreamState"), t.param("reason", "LocalVideoStreamReason"))),
32
32
  "onRemoteVideoStateChanged": t.opt(t.func("void", t.param("connection", "RtcConnection"), t.param("remoteUid", "number"), t.param("state", "RemoteVideoState"), t.param("reason", "RemoteVideoStateReason"), t.param("elapsed", "number"))),
33
33
  "onFirstRemoteVideoFrame": t.opt(t.func("void", t.param("connection", "RtcConnection"), t.param("remoteUid", "number"), t.param("width", "number"), t.param("height", "number"), t.param("elapsed", "number"))),
34
34
  "onUserJoined": t.opt(t.func("void", t.param("connection", "RtcConnection"), t.param("remoteUid", "number"), t.param("elapsed", "number"))),
@@ -38,8 +38,8 @@ export const IRtcEngineEventHandler = t.iface([], {
38
38
  "onUserEnableVideo": t.opt(t.func("void", t.param("connection", "RtcConnection"), t.param("remoteUid", "number"), t.param("enabled", "boolean"))),
39
39
  "onUserStateChanged": t.opt(t.func("void", t.param("connection", "RtcConnection"), t.param("remoteUid", "number"), t.param("state", "number"))),
40
40
  "onUserEnableLocalVideo": t.opt(t.func("void", t.param("connection", "RtcConnection"), t.param("remoteUid", "number"), t.param("enabled", "boolean"))),
41
- "onLocalAudioStats": t.opt(t.func("void", t.param("connection", "RtcConnection"), t.param("stats", "LocalAudioStats"))),
42
41
  "onRemoteAudioStats": t.opt(t.func("void", t.param("connection", "RtcConnection"), t.param("stats", "RemoteAudioStats"))),
42
+ "onLocalAudioStats": t.opt(t.func("void", t.param("connection", "RtcConnection"), t.param("stats", "LocalAudioStats"))),
43
43
  "onLocalVideoStats": t.opt(t.func("void", t.param("source", "VideoSourceType"), t.param("stats", "LocalVideoStats"))),
44
44
  "onRemoteVideoStats": t.opt(t.func("void", t.param("connection", "RtcConnection"), t.param("stats", "RemoteVideoStats"))),
45
45
  "onCameraReady": t.opt(t.func("void")),
@@ -48,7 +48,7 @@ export const IRtcEngineEventHandler = t.iface([], {
48
48
  "onFacePositionChanged": t.opt(t.func("void", t.param("imageWidth", "number"), t.param("imageHeight", "number"), t.param("vecRectangle", t.array("Rectangle")), t.param("vecDistance", t.array("number")), t.param("numFaces", "number"))),
49
49
  "onVideoStopped": t.opt(t.func("void")),
50
50
  "onAudioMixingStateChanged": t.opt(t.func("void", t.param("state", "AudioMixingStateType"), t.param("reason", "AudioMixingReasonType"))),
51
- "onRhythmPlayerStateChanged": t.opt(t.func("void", t.param("state", "RhythmPlayerStateType"), t.param("errorCode", "RhythmPlayerErrorType"))),
51
+ "onRhythmPlayerStateChanged": t.opt(t.func("void", t.param("state", "RhythmPlayerStateType"), t.param("reason", "RhythmPlayerReason"))),
52
52
  "onConnectionLost": t.opt(t.func("void", t.param("connection", "RtcConnection"))),
53
53
  "onConnectionInterrupted": t.opt(t.func("void", t.param("connection", "RtcConnection"))),
54
54
  "onConnectionBanned": t.opt(t.func("void", t.param("connection", "RtcConnection"))),
@@ -58,9 +58,9 @@ export const IRtcEngineEventHandler = t.iface([], {
58
58
  "onTokenPrivilegeWillExpire": t.opt(t.func("void", t.param("connection", "RtcConnection"), t.param("token", "string"))),
59
59
  "onLicenseValidationFailure": t.opt(t.func("void", t.param("connection", "RtcConnection"), t.param("reason", "LicenseErrorType"))),
60
60
  "onFirstLocalAudioFramePublished": t.opt(t.func("void", t.param("connection", "RtcConnection"), t.param("elapsed", "number"))),
61
- "onFirstRemoteAudioFrame": t.opt(t.func("void", t.param("connection", "RtcConnection"), t.param("userId", "number"), t.param("elapsed", "number"))),
62
61
  "onFirstRemoteAudioDecoded": t.opt(t.func("void", t.param("connection", "RtcConnection"), t.param("uid", "number"), t.param("elapsed", "number"))),
63
- "onLocalAudioStateChanged": t.opt(t.func("void", t.param("connection", "RtcConnection"), t.param("state", "LocalAudioStreamState"), t.param("error", "LocalAudioStreamError"))),
62
+ "onFirstRemoteAudioFrame": t.opt(t.func("void", t.param("connection", "RtcConnection"), t.param("userId", "number"), t.param("elapsed", "number"))),
63
+ "onLocalAudioStateChanged": t.opt(t.func("void", t.param("connection", "RtcConnection"), t.param("state", "LocalAudioStreamState"), t.param("reason", "LocalAudioStreamReason"))),
64
64
  "onRemoteAudioStateChanged": t.opt(t.func("void", t.param("connection", "RtcConnection"), t.param("remoteUid", "number"), t.param("state", "RemoteAudioState"), t.param("reason", "RemoteAudioStateReason"), t.param("elapsed", "number"))),
65
65
  "onActiveSpeaker": t.opt(t.func("void", t.param("connection", "RtcConnection"), t.param("uid", "number"))),
66
66
  "onContentInspectResult": t.opt(t.func("void", t.param("result", "ContentInspectResult"))),
@@ -68,12 +68,11 @@ export const IRtcEngineEventHandler = t.iface([], {
68
68
  "onClientRoleChanged": t.opt(t.func("void", t.param("connection", "RtcConnection"), t.param("oldRole", "ClientRoleType"), t.param("newRole", "ClientRoleType"), t.param("newRoleOptions", "ClientRoleOptions"))),
69
69
  "onClientRoleChangeFailed": t.opt(t.func("void", t.param("connection", "RtcConnection"), t.param("reason", "ClientRoleChangeFailedReason"), t.param("currentRole", "ClientRoleType"))),
70
70
  "onAudioDeviceVolumeChanged": t.opt(t.func("void", t.param("deviceType", "MediaDeviceType"), t.param("volume", "number"), t.param("muted", "boolean"))),
71
- "onRtmpStreamingStateChanged": t.opt(t.func("void", t.param("url", "string"), t.param("state", "RtmpStreamPublishState"), t.param("errCode", "RtmpStreamPublishErrorType"))),
71
+ "onRtmpStreamingStateChanged": t.opt(t.func("void", t.param("url", "string"), t.param("state", "RtmpStreamPublishState"), t.param("reason", "RtmpStreamPublishReason"))),
72
72
  "onRtmpStreamingEvent": t.opt(t.func("void", t.param("url", "string"), t.param("eventCode", "RtmpStreamingEvent"))),
73
73
  "onTranscodingUpdated": t.opt(t.func("void")),
74
74
  "onAudioRoutingChanged": t.opt(t.func("void", t.param("routing", "number"))),
75
75
  "onChannelMediaRelayStateChanged": t.opt(t.func("void", t.param("state", "ChannelMediaRelayState"), t.param("code", "ChannelMediaRelayError"))),
76
- "onChannelMediaRelayEvent": t.opt(t.func("void", t.param("code", "ChannelMediaRelayEvent"))),
77
76
  "onLocalPublishFallbackToAudioOnly": t.opt(t.func("void", t.param("isFallbackOrRecover", "boolean"))),
78
77
  "onRemoteSubscribeFallbackToAudioOnly": t.opt(t.func("void", t.param("uid", "number"), t.param("isFallbackOrRecover", "boolean"))),
79
78
  "onRemoteAudioTransportStats": t.opt(t.func("void", t.param("connection", "RtcConnection"), t.param("remoteUid", "number"), t.param("delay", "number"), t.param("lost", "number"), t.param("rxKBitRate", "number"))),
@@ -86,18 +85,20 @@ export const IRtcEngineEventHandler = t.iface([], {
86
85
  "onPermissionError": t.opt(t.func("void", t.param("permissionType", "PermissionType"))),
87
86
  "onLocalUserRegistered": t.opt(t.func("void", t.param("uid", "number"), t.param("userAccount", "string"))),
88
87
  "onUserInfoUpdated": t.opt(t.func("void", t.param("uid", "number"), t.param("info", "UserInfo"))),
88
+ "onUserAccountUpdated": t.opt(t.func("void", t.param("connection", "RtcConnection"), t.param("remoteUid", "number"), t.param("remoteUserAccount", "string"))),
89
+ "onVideoRenderingTracingResult": t.opt(t.func("void", t.param("connection", "RtcConnection"), t.param("uid", "number"), t.param("currentEvent", "MediaTraceEvent"), t.param("tracingInfo", "VideoRenderingTracingInfo"))),
90
+ "onLocalVideoTranscoderError": t.opt(t.func("void", t.param("stream", "TranscodingVideoStream"), t.param("error", "VideoTranscoderError"))),
89
91
  "onUploadLogResult": t.opt(t.func("void", t.param("connection", "RtcConnection"), t.param("requestId", "string"), t.param("success", "boolean"), t.param("reason", "UploadErrorReason"))),
90
92
  "onAudioSubscribeStateChanged": t.opt(t.func("void", t.param("channel", "string"), t.param("uid", "number"), t.param("oldState", "StreamSubscribeState"), t.param("newState", "StreamSubscribeState"), t.param("elapseSinceLastState", "number"))),
91
93
  "onVideoSubscribeStateChanged": t.opt(t.func("void", t.param("channel", "string"), t.param("uid", "number"), t.param("oldState", "StreamSubscribeState"), t.param("newState", "StreamSubscribeState"), t.param("elapseSinceLastState", "number"))),
92
94
  "onAudioPublishStateChanged": t.opt(t.func("void", t.param("channel", "string"), t.param("oldState", "StreamPublishState"), t.param("newState", "StreamPublishState"), t.param("elapseSinceLastState", "number"))),
93
95
  "onVideoPublishStateChanged": t.opt(t.func("void", t.param("source", "VideoSourceType"), t.param("channel", "string"), t.param("oldState", "StreamPublishState"), t.param("newState", "StreamPublishState"), t.param("elapseSinceLastState", "number"))),
96
+ "onTranscodedStreamLayoutInfo": t.opt(t.func("void", t.param("connection", "RtcConnection"), t.param("uid", "number"), t.param("width", "number"), t.param("height", "number"), t.param("layoutCount", "number"), t.param("layoutlist", t.array("VideoLayout")))),
94
97
  "onExtensionEvent": t.opt(t.func("void", t.param("provider", "string"), t.param("extension", "string"), t.param("key", "string"), t.param("value", "string"))),
95
98
  "onExtensionStarted": t.opt(t.func("void", t.param("provider", "string"), t.param("extension", "string"))),
96
99
  "onExtensionStopped": t.opt(t.func("void", t.param("provider", "string"), t.param("extension", "string"))),
97
100
  "onExtensionError": t.opt(t.func("void", t.param("provider", "string"), t.param("extension", "string"), t.param("error", "number"), t.param("message", "string"))),
98
- "onUserAccountUpdated": t.opt(t.func("void", t.param("connection", "RtcConnection"), t.param("remoteUid", "number"), t.param("userAccount", "string"))),
99
- "onLocalVideoTranscoderError": t.opt(t.func("void", t.param("stream", "TranscodingVideoStream"), t.param("error", "VideoTranscoderError"))),
100
- "onVideoRenderingTracingResult": t.opt(t.func("void", t.param("connection", "RtcConnection"), t.param("uid", "number"), t.param("currentEvent", "MediaTraceEvent"), t.param("tracingInfo", "VideoRenderingTracingInfo"))),
101
+ "onSetRtmFlagResult": t.opt(t.func("void", t.param("connection", "RtcConnection"), t.param("code", "number"))),
101
102
  });
102
103
 
103
104
  export const IMetadataObserver = t.iface([], {
@@ -105,7 +106,7 @@ export const IMetadataObserver = t.iface([], {
105
106
  });
106
107
 
107
108
  export const IDirectCdnStreamingEventHandler = t.iface([], {
108
- "onDirectCdnStreamingStateChanged": t.opt(t.func("void", t.param("state", "DirectCdnStreamingState"), t.param("error", "DirectCdnStreamingError"), t.param("message", "string"))),
109
+ "onDirectCdnStreamingStateChanged": t.opt(t.func("void", t.param("state", "DirectCdnStreamingState"), t.param("reason", "DirectCdnStreamingReason"), t.param("message", "string"))),
109
110
  "onDirectCdnStreamingStats": t.opt(t.func("void", t.param("stats", "DirectCdnStreamingStats"))),
110
111
  });
111
112
 
@@ -1,3 +1,4 @@
1
+ import { VideoMirrorModeType, VideoViewSetupMode } from '../Private/AgoraBase';
1
2
  import { RenderModeType, VideoSourceType } from '../Private/AgoraMediaBase';
2
3
  import { AgoraEnv } from '../Utils';
3
4
 
@@ -70,12 +71,12 @@ export default class AgoraView extends HTMLElement {
70
71
  return observedAttributes;
71
72
  }
72
73
 
73
- get videoSourceType(): VideoSourceType {
74
+ get sourceType(): VideoSourceType {
74
75
  const number = Number(this.getAttribute(VIDEO_SOURCE_TYPE_STRING));
75
76
  return isNaN(number) ? 0 : number;
76
77
  }
77
78
 
78
- set videoSourceType(val) {
79
+ set sourceType(val) {
79
80
  if (val) {
80
81
  this.setAttribute(VIDEO_SOURCE_TYPE_STRING, String(val));
81
82
  } else {
@@ -108,7 +109,7 @@ export default class AgoraView extends HTMLElement {
108
109
  }
109
110
  }
110
111
 
111
- get renderContentMode(): RenderModeType {
112
+ get renderMode(): RenderModeType {
112
113
  const number = Number(
113
114
  this.getAttribute(RENDERER_CONTENT_MODE_STRING) ||
114
115
  RenderModeType.RenderModeFit
@@ -116,7 +117,7 @@ export default class AgoraView extends HTMLElement {
116
117
  return isNaN(number) ? RenderModeType.RenderModeFit : number;
117
118
  }
118
119
 
119
- set renderContentMode(val) {
120
+ set renderMode(val) {
120
121
  if (val) {
121
122
  this.setAttribute(RENDERER_CONTENT_MODE_STRING, String(val));
122
123
  } else {
@@ -141,21 +142,28 @@ export default class AgoraView extends HTMLElement {
141
142
  }
142
143
 
143
144
  initializeRender = () => {
144
- AgoraEnv.AgoraRendererManager?.destroyRendererByView(this);
145
- AgoraEnv.AgoraRendererManager?.setupVideo({
146
- videoSourceType: this.videoSourceType,
145
+ const { channelId, uid, sourceType, renderMode, renderMirror } = this;
146
+ AgoraEnv.AgoraRendererManager?.addOrRemoveRenderer({
147
+ sourceType,
147
148
  view: this,
148
- uid: this.uid,
149
- channelId: this.channelId,
150
- rendererOptions: {
151
- mirror: this.renderMirror,
152
- contentMode: this.renderContentMode,
153
- },
149
+ uid,
150
+ channelId,
151
+ renderMode,
152
+ mirrorMode: renderMirror
153
+ ? VideoMirrorModeType.VideoMirrorModeEnabled
154
+ : VideoMirrorModeType.VideoMirrorModeDisabled,
155
+ setupMode: VideoViewSetupMode.VideoViewSetupReplace,
154
156
  });
155
157
  };
156
158
 
157
159
  destroyRender = () => {
158
- AgoraEnv.AgoraRendererManager?.destroyRendererByView(this);
160
+ const { channelId, uid, sourceType } = this;
161
+ AgoraEnv.AgoraRendererManager?.removeRendererFromCache({
162
+ channelId,
163
+ uid,
164
+ sourceType,
165
+ view: this,
166
+ });
159
167
  };
160
168
 
161
169
  connectedCallback() {
@@ -173,11 +181,13 @@ export default class AgoraView extends HTMLElement {
173
181
  ].includes(attrName);
174
182
 
175
183
  if (isSetRenderOption) {
176
- AgoraEnv.AgoraRendererManager?.setRenderOption(
177
- this,
178
- this.renderContentMode,
179
- this.renderMirror
180
- );
184
+ AgoraEnv.AgoraRendererManager?.setRendererContext({
185
+ view: this,
186
+ renderMode: this.renderMode,
187
+ mirrorMode: this.renderMirror
188
+ ? VideoMirrorModeType.VideoMirrorModeEnabled
189
+ : VideoMirrorModeType.VideoMirrorModeDisabled,
190
+ });
181
191
  return;
182
192
  }
183
193
  const isNeedReInitialize = observedAttributes.includes(attrName);
@@ -1,19 +1,14 @@
1
- import { RenderModeType } from '../Private/AgoraMediaBase';
2
- import { RendererOptions, ShareVideoFrame } from '../Types';
1
+ import { VideoMirrorModeType } from '../Private/AgoraBase';
2
+ import { RenderModeType, VideoFrame } from '../Private/AgoraMediaBase';
3
+ import { RendererContext } from '../Types';
4
+
5
+ type Context = Pick<RendererContext, 'renderMode' | 'mirrorMode'>;
3
6
 
4
7
  export abstract class IRenderer {
5
8
  parentElement?: HTMLElement;
6
9
  container?: HTMLElement;
7
10
  canvas?: HTMLCanvasElement;
8
- contentMode = RenderModeType.RenderModeHidden;
9
- mirror?: boolean;
10
-
11
- public snapshot(fileType = 'image/png') {
12
- if (this.canvas && this.canvas.toDataURL) {
13
- return this.canvas.toDataURL(fileType);
14
- }
15
- return null;
16
- }
11
+ _context: Context = {};
17
12
 
18
13
  public bind(element: HTMLElement) {
19
14
  this.parentElement = element;
@@ -47,22 +42,76 @@ export abstract class IRenderer {
47
42
  this.parentElement = undefined;
48
43
  }
49
44
 
50
- public equalsElement(element: Element): boolean {
51
- if (!this.parentElement) {
52
- console.error('parentElement is null');
45
+ public abstract drawFrame(videoFrame: VideoFrame): void;
46
+
47
+ public set context({ renderMode, mirrorMode }: Context) {
48
+ if (this.context.renderMode !== renderMode) {
49
+ this.context.renderMode = renderMode;
50
+ this.updateRenderMode();
51
+ }
52
+
53
+ if (this.context.mirrorMode !== mirrorMode) {
54
+ this.context.mirrorMode = mirrorMode;
55
+ this.updateMirrorMode();
53
56
  }
54
- return element === this.parentElement;
55
57
  }
56
58
 
57
- abstract drawFrame(imageData: ShareVideoFrame): void;
59
+ public get context(): Context {
60
+ return this._context;
61
+ }
62
+
63
+ protected updateRenderMode() {
64
+ if (!this.canvas || !this.container) return;
65
+
66
+ const { clientWidth, clientHeight } = this.container;
67
+ const { width, height } = this.canvas;
58
68
 
59
- public setRenderOption({ contentMode, mirror }: RendererOptions) {
60
- this.contentMode = contentMode ?? RenderModeType.RenderModeFit;
61
- this.mirror = mirror;
62
- Object.assign(this.parentElement!.style, {
63
- transform: mirror ? 'rotateY(180deg)' : '',
69
+ const containerAspectRatio = clientWidth / clientHeight;
70
+ const canvasAspectRatio = width / height;
71
+ const widthScale = clientWidth / width;
72
+ const heightScale = clientHeight / height;
73
+
74
+ const isHidden =
75
+ this.context?.renderMode === RenderModeType.RenderModeHidden;
76
+
77
+ let scale = 1;
78
+ // If container's aspect ratio is larger than canvas's aspect ratio
79
+ if (containerAspectRatio > canvasAspectRatio) {
80
+ // Scale canvas to fit container's width on hidden mode
81
+ // Scale canvas to fit container's height on fit mode
82
+ scale = isHidden ? widthScale : heightScale;
83
+ } else {
84
+ // Scale canvas to fit container's height on hidden mode
85
+ // Scale canvas to fit container's width on fit mode
86
+ scale = isHidden ? heightScale : widthScale;
87
+ }
88
+ this.canvas.style.transform = `scale(${scale})`;
89
+ }
90
+
91
+ protected updateMirrorMode(): void {
92
+ if (!this.parentElement) return;
93
+
94
+ Object.assign(this.parentElement.style, {
95
+ transform:
96
+ this.context.mirrorMode === VideoMirrorModeType.VideoMirrorModeEnabled
97
+ ? 'rotateY(180deg)'
98
+ : '',
64
99
  });
65
100
  }
66
101
 
67
- abstract refreshCanvas(): void;
102
+ protected rotateCanvas({ width, height, rotation }: VideoFrame): void {
103
+ if (!this.canvas) return;
104
+
105
+ if (rotation === 0 || rotation === 180) {
106
+ this.canvas.width = width!;
107
+ this.canvas.height = height!;
108
+ } else if (rotation === 90 || rotation === 270) {
109
+ this.canvas.height = width!;
110
+ this.canvas.width = height!;
111
+ } else {
112
+ throw new Error(
113
+ `Invalid rotation: ${rotation}, only 0, 90, 180, 270 are supported`
114
+ );
115
+ }
116
+ }
68
117
  }
@@ -1,35 +1,289 @@
1
+ import { VideoMirrorModeType, VideoViewSetupMode } from '../Private/AgoraBase';
1
2
  import { RenderModeType, VideoSourceType } from '../Private/AgoraMediaBase';
2
- import { Channel, RendererVideoConfig } from '../Types';
3
+ import { RendererContext, RendererType } from '../Types';
4
+ import { logDebug } from '../Utils';
5
+
6
+ import { IRenderer } from './IRenderer';
7
+ import { RendererCache, generateRendererCacheKey } from './RendererCache';
3
8
 
4
9
  /**
5
10
  * @ignore
6
11
  */
7
12
  export abstract class IRendererManager {
8
- abstract get defaultRenderConfig(): RendererVideoConfig;
13
+ /**
14
+ * @ignore
15
+ */
16
+ private _renderingFps: number;
17
+ /**
18
+ * @ignore
19
+ */
20
+ private _currentFrameCount: number;
21
+ /**
22
+ * @ignore
23
+ */
24
+ private _previousFirstFrameTime: number;
25
+ /**
26
+ * @ignore
27
+ */
28
+ private _renderingTimer?: number;
29
+ /**
30
+ * @ignore
31
+ */
32
+ private _rendererCaches: RendererCache[];
33
+ /**
34
+ * @ignore
35
+ */
36
+ private _context: RendererContext;
37
+
38
+ constructor() {
39
+ this._renderingFps = 15;
40
+ this._currentFrameCount = 0;
41
+ this._previousFirstFrameTime = 0;
42
+ this._rendererCaches = [];
43
+ this._context = {
44
+ renderMode: RenderModeType.RenderModeHidden,
45
+ mirrorMode: VideoMirrorModeType.VideoMirrorModeDisabled,
46
+ };
47
+ }
48
+
49
+ public set renderingFps(fps: number) {
50
+ if (this._renderingFps !== fps) {
51
+ this._renderingFps = fps;
52
+ if (this._renderingTimer) {
53
+ this.stopRendering();
54
+ this.startRendering();
55
+ }
56
+ }
57
+ }
58
+
59
+ public get renderingFps(): number {
60
+ return this._renderingFps;
61
+ }
62
+
63
+ public set defaultChannelId(channelId: string) {
64
+ this._context.channelId = channelId;
65
+ }
66
+
67
+ public get defaultChannelId(): string {
68
+ return this._context.channelId ?? '';
69
+ }
70
+
71
+ public get defaultRenderMode(): RenderModeType {
72
+ return this._context.renderMode!;
73
+ }
74
+
75
+ public get defaultMirrorMode(): VideoMirrorModeType {
76
+ return this._context.mirrorMode!;
77
+ }
78
+
79
+ public release(): void {
80
+ this.stopRendering();
81
+ this.clearRendererCache();
82
+ }
83
+
84
+ private precheckRendererContext(context: RendererContext): RendererContext {
85
+ let {
86
+ sourceType,
87
+ uid,
88
+ channelId,
89
+ mediaPlayerId,
90
+ renderMode = this.defaultRenderMode,
91
+ mirrorMode = this.defaultMirrorMode,
92
+ } = context;
93
+ switch (sourceType) {
94
+ case VideoSourceType.VideoSourceRemote:
95
+ if (uid === undefined) {
96
+ throw new Error('uid is required');
97
+ }
98
+ channelId = channelId ?? this.defaultChannelId;
99
+ break;
100
+ case VideoSourceType.VideoSourceMediaPlayer:
101
+ if (mediaPlayerId === undefined) {
102
+ throw new Error('mediaPlayerId is required');
103
+ }
104
+ channelId = '';
105
+ uid = mediaPlayerId;
106
+ break;
107
+ case undefined:
108
+ if (uid) {
109
+ sourceType = VideoSourceType.VideoSourceRemote;
110
+ }
111
+ break;
112
+ default:
113
+ channelId = '';
114
+ uid = 0;
115
+ break;
116
+ }
117
+ return { ...context, sourceType, uid, channelId, renderMode, mirrorMode };
118
+ }
119
+
120
+ public addOrRemoveRenderer(
121
+ context: RendererContext
122
+ ): RendererCache | undefined {
123
+ // To be compatible with the old API
124
+ let { setupMode = VideoViewSetupMode.VideoViewSetupAdd } = context;
125
+ if (!context.view) setupMode = VideoViewSetupMode.VideoViewSetupRemove;
126
+ switch (setupMode) {
127
+ case VideoViewSetupMode.VideoViewSetupAdd:
128
+ return this.addRendererToCache(context);
129
+ case VideoViewSetupMode.VideoViewSetupRemove:
130
+ this.removeRendererFromCache(context);
131
+ return undefined;
132
+ case VideoViewSetupMode.VideoViewSetupReplace:
133
+ this.removeRendererFromCache(context);
134
+ return this.addRendererToCache(context);
135
+ }
136
+ }
137
+
138
+ private addRendererToCache(
139
+ context: RendererContext
140
+ ): RendererCache | undefined {
141
+ const checkedContext = this.precheckRendererContext(context);
142
+
143
+ if (!checkedContext.view) return undefined;
144
+
145
+ if (this.findRenderer(checkedContext.view)) {
146
+ throw new Error('You have already added this view to the renderer');
147
+ }
148
+
149
+ let rendererCache = this.getRendererCache(checkedContext);
150
+ if (!rendererCache) {
151
+ rendererCache = new RendererCache(checkedContext);
152
+ this._rendererCaches.push(rendererCache);
153
+ }
154
+ rendererCache.addRenderer(this.createRenderer(checkedContext));
155
+ this.startRendering();
156
+ return rendererCache;
157
+ }
158
+
159
+ public removeRendererFromCache(context: RendererContext): void {
160
+ const checkedContext = this.precheckRendererContext(context);
161
+
162
+ const rendererCache = this.getRendererCache(checkedContext);
163
+ if (!rendererCache) return;
164
+ if (checkedContext.view) {
165
+ const renderer = rendererCache.findRenderer(checkedContext.view);
166
+ if (!renderer) return;
167
+ rendererCache.removeRenderer(renderer);
168
+ } else {
169
+ rendererCache.removeRenderer();
170
+ }
171
+ if (rendererCache.renderers.length === 0) {
172
+ this._rendererCaches.splice(
173
+ this._rendererCaches.indexOf(rendererCache),
174
+ 1
175
+ );
176
+ }
177
+ }
178
+
179
+ public clearRendererCache(): void {
180
+ for (const rendererCache of this._rendererCaches) {
181
+ rendererCache.removeRenderer();
182
+ }
183
+ this._rendererCaches.splice(0);
184
+ }
185
+
186
+ public getRendererCache(context: RendererContext): RendererCache | undefined {
187
+ return this._rendererCaches.find(
188
+ (cache) => cache.key === generateRendererCacheKey(context)
189
+ );
190
+ }
191
+
192
+ public getRenderers(context: RendererContext): IRenderer[] {
193
+ return this.getRendererCache(context)?.renderers || [];
194
+ }
195
+
196
+ public findRenderer(view: Element): IRenderer | undefined {
197
+ for (const rendererCache of this._rendererCaches) {
198
+ const renderer = rendererCache.findRenderer(view);
199
+ if (renderer) return renderer;
200
+ }
201
+ return undefined;
202
+ }
203
+
204
+ protected abstract createRenderer(
205
+ context: RendererContext,
206
+ rendererType?: RendererType
207
+ ): IRenderer;
208
+
209
+ public startRendering(): void {
210
+ if (this._renderingTimer) return;
211
+
212
+ const renderingLooper = () => {
213
+ if (this._previousFirstFrameTime === 0) {
214
+ // Get the current time as the time of the first frame of per second
215
+ this._previousFirstFrameTime = performance.now();
216
+ // Reset the frame count
217
+ this._currentFrameCount = 0;
218
+ }
219
+
220
+ // Increase the frame count
221
+ ++this._currentFrameCount;
9
222
 
10
- abstract enableRender(enabled?: boolean): void;
223
+ // Get the current time
224
+ const currentFrameTime = performance.now();
225
+ // Calculate the time difference between the current frame and the previous frame
226
+ const deltaTime = currentFrameTime - this._previousFirstFrameTime;
227
+ // Calculate the expected time of the current frame
228
+ const expectedTime =
229
+ (this._currentFrameCount * 1000) / this._renderingFps;
230
+ logDebug(
231
+ new Date().toLocaleTimeString(),
232
+ 'currentFrameCount',
233
+ this._currentFrameCount,
234
+ 'expectedTime',
235
+ expectedTime,
236
+ 'deltaTime',
237
+ deltaTime
238
+ );
11
239
 
12
- abstract clear(): void;
240
+ if (this._rendererCaches.length === 0) {
241
+ // If there is no renderer, stop rendering
242
+ this.stopRendering();
243
+ return;
244
+ }
13
245
 
14
- abstract setupVideo(rendererVideoConfig: RendererVideoConfig): number;
246
+ // Render all renderers
247
+ for (const rendererCache of this._rendererCaches) {
248
+ this.doRendering(rendererCache);
249
+ }
15
250
 
16
- abstract setupLocalVideo(rendererConfig: RendererVideoConfig): number;
251
+ if (this._currentFrameCount >= this.renderingFps) {
252
+ this._previousFirstFrameTime = 0;
253
+ }
17
254
 
18
- abstract setupRemoteVideo(rendererConfig: RendererVideoConfig): number;
255
+ if (deltaTime < expectedTime) {
256
+ // If the time difference between the current frame and the previous frame is less than the expected time, then wait for the difference
257
+ this._renderingTimer = window.setTimeout(
258
+ renderingLooper,
259
+ expectedTime - deltaTime
260
+ );
261
+ } else {
262
+ // If the time difference between the current frame and the previous frame is greater than the expected time, then render immediately
263
+ renderingLooper();
264
+ }
265
+ };
266
+ renderingLooper();
267
+ }
19
268
 
20
- abstract setRenderOptionByConfig(rendererConfig: RendererVideoConfig): number;
269
+ public abstract doRendering(rendererCache: RendererCache): void;
21
270
 
22
- abstract destroyRendererByView(view: Element): void;
271
+ public stopRendering(): void {
272
+ if (this._renderingTimer) {
273
+ window.clearTimeout(this._renderingTimer);
274
+ this._renderingTimer = undefined;
275
+ }
276
+ }
23
277
 
24
- abstract destroyRenderersByConfig(
25
- videoSourceType: VideoSourceType,
26
- channelId?: Channel,
27
- uid?: number
28
- ): void;
278
+ public setRendererContext(context: RendererContext): boolean {
279
+ const checkedContext = this.precheckRendererContext(context);
29
280
 
30
- abstract setRenderOption(
31
- view: HTMLElement,
32
- contentMode?: RenderModeType,
33
- mirror?: boolean
34
- ): void;
281
+ for (const rendererCache of this._rendererCaches) {
282
+ const result = rendererCache.setRendererContext(checkedContext);
283
+ if (result) {
284
+ return true;
285
+ }
286
+ }
287
+ return false;
288
+ }
35
289
  }