safeness-sb-new 0.0.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 (343) hide show
  1. package/README.md +115 -0
  2. package/package.json +96 -0
  3. package/src/WebSocket.js +39 -0
  4. package/src/client/BaseClient.js +86 -0
  5. package/src/client/Client.js +836 -0
  6. package/src/client/WebhookClient.js +61 -0
  7. package/src/client/actions/Action.js +120 -0
  8. package/src/client/actions/ActionsManager.js +78 -0
  9. package/src/client/actions/ApplicationCommandPermissionsUpdate.js +34 -0
  10. package/src/client/actions/AutoModerationActionExecution.js +27 -0
  11. package/src/client/actions/AutoModerationRuleCreate.js +28 -0
  12. package/src/client/actions/AutoModerationRuleDelete.js +32 -0
  13. package/src/client/actions/AutoModerationRuleUpdate.js +30 -0
  14. package/src/client/actions/ChannelCreate.js +23 -0
  15. package/src/client/actions/ChannelDelete.js +39 -0
  16. package/src/client/actions/ChannelUpdate.js +43 -0
  17. package/src/client/actions/GuildAuditLogEntryCreate.js +29 -0
  18. package/src/client/actions/GuildBanAdd.js +20 -0
  19. package/src/client/actions/GuildBanRemove.js +25 -0
  20. package/src/client/actions/GuildChannelsPositionUpdate.js +21 -0
  21. package/src/client/actions/GuildDelete.js +65 -0
  22. package/src/client/actions/GuildEmojiCreate.js +20 -0
  23. package/src/client/actions/GuildEmojiDelete.js +21 -0
  24. package/src/client/actions/GuildEmojiUpdate.js +20 -0
  25. package/src/client/actions/GuildEmojisUpdate.js +34 -0
  26. package/src/client/actions/GuildIntegrationsUpdate.js +19 -0
  27. package/src/client/actions/GuildMemberRemove.js +33 -0
  28. package/src/client/actions/GuildMemberUpdate.js +44 -0
  29. package/src/client/actions/GuildRoleCreate.js +25 -0
  30. package/src/client/actions/GuildRoleDelete.js +31 -0
  31. package/src/client/actions/GuildRoleUpdate.js +39 -0
  32. package/src/client/actions/GuildRolesPositionUpdate.js +21 -0
  33. package/src/client/actions/GuildScheduledEventCreate.js +27 -0
  34. package/src/client/actions/GuildScheduledEventDelete.js +31 -0
  35. package/src/client/actions/GuildScheduledEventUpdate.js +30 -0
  36. package/src/client/actions/GuildScheduledEventUserAdd.js +32 -0
  37. package/src/client/actions/GuildScheduledEventUserRemove.js +32 -0
  38. package/src/client/actions/GuildStickerCreate.js +20 -0
  39. package/src/client/actions/GuildStickerDelete.js +21 -0
  40. package/src/client/actions/GuildStickerUpdate.js +20 -0
  41. package/src/client/actions/GuildStickersUpdate.js +34 -0
  42. package/src/client/actions/GuildUpdate.js +33 -0
  43. package/src/client/actions/InviteCreate.js +28 -0
  44. package/src/client/actions/InviteDelete.js +30 -0
  45. package/src/client/actions/MessageCreate.js +46 -0
  46. package/src/client/actions/MessageDelete.js +32 -0
  47. package/src/client/actions/MessageDeleteBulk.js +46 -0
  48. package/src/client/actions/MessageReactionAdd.js +56 -0
  49. package/src/client/actions/MessageReactionRemove.js +45 -0
  50. package/src/client/actions/MessageReactionRemoveAll.js +33 -0
  51. package/src/client/actions/MessageReactionRemoveEmoji.js +28 -0
  52. package/src/client/actions/MessageUpdate.js +26 -0
  53. package/src/client/actions/PresenceUpdate.js +46 -0
  54. package/src/client/actions/StageInstanceCreate.js +28 -0
  55. package/src/client/actions/StageInstanceDelete.js +33 -0
  56. package/src/client/actions/StageInstanceUpdate.js +30 -0
  57. package/src/client/actions/ThreadCreate.js +24 -0
  58. package/src/client/actions/ThreadDelete.js +32 -0
  59. package/src/client/actions/ThreadListSync.js +59 -0
  60. package/src/client/actions/ThreadMemberUpdate.js +30 -0
  61. package/src/client/actions/ThreadMembersUpdate.js +34 -0
  62. package/src/client/actions/TypingStart.js +29 -0
  63. package/src/client/actions/UserUpdate.js +35 -0
  64. package/src/client/actions/VoiceStateUpdate.js +57 -0
  65. package/src/client/actions/WebhooksUpdate.js +20 -0
  66. package/src/client/voice/ClientVoiceManager.js +150 -0
  67. package/src/client/voice/VoiceConnection.js +849 -0
  68. package/src/client/voice/dispatcher/AnnexBDispatcher.js +120 -0
  69. package/src/client/voice/dispatcher/AudioDispatcher.js +115 -0
  70. package/src/client/voice/dispatcher/BaseDispatcher.js +405 -0
  71. package/src/client/voice/dispatcher/VPxDispatcher.js +52 -0
  72. package/src/client/voice/dispatcher/VideoDispatcher.js +31 -0
  73. package/src/client/voice/networking/VoiceUDPClient.js +188 -0
  74. package/src/client/voice/networking/VoiceWebSocket.js +280 -0
  75. package/src/client/voice/player/MediaPlayer.js +294 -0
  76. package/src/client/voice/player/processing/AnnexBNalSplitter.js +244 -0
  77. package/src/client/voice/player/processing/IvfSplitter.js +106 -0
  78. package/src/client/voice/receiver/PacketHandler.js +170 -0
  79. package/src/client/voice/receiver/Receiver.js +82 -0
  80. package/src/client/voice/receiver/video/IvfJoinner.js +106 -0
  81. package/src/client/voice/util/Function.js +14 -0
  82. package/src/client/voice/util/PlayInterface.js +122 -0
  83. package/src/client/voice/util/Secretbox.js +42 -0
  84. package/src/client/voice/util/Silence.js +16 -0
  85. package/src/client/voice/util/Socket.js +62 -0
  86. package/src/client/voice/util/VolumeInterface.js +104 -0
  87. package/src/client/websocket/WebSocketManager.js +392 -0
  88. package/src/client/websocket/WebSocketShard.js +906 -0
  89. package/src/client/websocket/handlers/APPLICATION_COMMAND_CREATE.js +18 -0
  90. package/src/client/websocket/handlers/APPLICATION_COMMAND_DELETE.js +20 -0
  91. package/src/client/websocket/handlers/APPLICATION_COMMAND_PERMISSIONS_UPDATE.js +5 -0
  92. package/src/client/websocket/handlers/APPLICATION_COMMAND_UPDATE.js +20 -0
  93. package/src/client/websocket/handlers/AUTO_MODERATION_ACTION_EXECUTION.js +5 -0
  94. package/src/client/websocket/handlers/AUTO_MODERATION_RULE_CREATE.js +5 -0
  95. package/src/client/websocket/handlers/AUTO_MODERATION_RULE_DELETE.js +5 -0
  96. package/src/client/websocket/handlers/AUTO_MODERATION_RULE_UPDATE.js +5 -0
  97. package/src/client/websocket/handlers/CALL_CREATE.js +14 -0
  98. package/src/client/websocket/handlers/CALL_DELETE.js +11 -0
  99. package/src/client/websocket/handlers/CALL_UPDATE.js +11 -0
  100. package/src/client/websocket/handlers/CHANNEL_CREATE.js +5 -0
  101. package/src/client/websocket/handlers/CHANNEL_DELETE.js +5 -0
  102. package/src/client/websocket/handlers/CHANNEL_PINS_UPDATE.js +22 -0
  103. package/src/client/websocket/handlers/CHANNEL_RECIPIENT_ADD.js +19 -0
  104. package/src/client/websocket/handlers/CHANNEL_RECIPIENT_REMOVE.js +16 -0
  105. package/src/client/websocket/handlers/CHANNEL_UPDATE.js +16 -0
  106. package/src/client/websocket/handlers/GUILD_AUDIT_LOG_ENTRY_CREATE.js +5 -0
  107. package/src/client/websocket/handlers/GUILD_BAN_ADD.js +5 -0
  108. package/src/client/websocket/handlers/GUILD_BAN_REMOVE.js +5 -0
  109. package/src/client/websocket/handlers/GUILD_CREATE.js +52 -0
  110. package/src/client/websocket/handlers/GUILD_DELETE.js +5 -0
  111. package/src/client/websocket/handlers/GUILD_EMOJIS_UPDATE.js +5 -0
  112. package/src/client/websocket/handlers/GUILD_INTEGRATIONS_UPDATE.js +5 -0
  113. package/src/client/websocket/handlers/GUILD_MEMBERS_CHUNK.js +39 -0
  114. package/src/client/websocket/handlers/GUILD_MEMBER_ADD.js +20 -0
  115. package/src/client/websocket/handlers/GUILD_MEMBER_REMOVE.js +5 -0
  116. package/src/client/websocket/handlers/GUILD_MEMBER_UPDATE.js +5 -0
  117. package/src/client/websocket/handlers/GUILD_ROLE_CREATE.js +5 -0
  118. package/src/client/websocket/handlers/GUILD_ROLE_DELETE.js +5 -0
  119. package/src/client/websocket/handlers/GUILD_ROLE_UPDATE.js +5 -0
  120. package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_CREATE.js +5 -0
  121. package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_DELETE.js +5 -0
  122. package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_UPDATE.js +5 -0
  123. package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_USER_ADD.js +5 -0
  124. package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_USER_REMOVE.js +5 -0
  125. package/src/client/websocket/handlers/GUILD_STICKERS_UPDATE.js +5 -0
  126. package/src/client/websocket/handlers/GUILD_UPDATE.js +5 -0
  127. package/src/client/websocket/handlers/INTERACTION_MODAL_CREATE.js +12 -0
  128. package/src/client/websocket/handlers/INVITE_CREATE.js +5 -0
  129. package/src/client/websocket/handlers/INVITE_DELETE.js +5 -0
  130. package/src/client/websocket/handlers/MESSAGE_CREATE.js +5 -0
  131. package/src/client/websocket/handlers/MESSAGE_DELETE.js +5 -0
  132. package/src/client/websocket/handlers/MESSAGE_DELETE_BULK.js +5 -0
  133. package/src/client/websocket/handlers/MESSAGE_POLL_VOTE_ADD.js +22 -0
  134. package/src/client/websocket/handlers/MESSAGE_POLL_VOTE_REMOVE.js +12 -0
  135. package/src/client/websocket/handlers/MESSAGE_REACTION_ADD.js +5 -0
  136. package/src/client/websocket/handlers/MESSAGE_REACTION_REMOVE.js +5 -0
  137. package/src/client/websocket/handlers/MESSAGE_REACTION_REMOVE_ALL.js +5 -0
  138. package/src/client/websocket/handlers/MESSAGE_REACTION_REMOVE_EMOJI.js +5 -0
  139. package/src/client/websocket/handlers/MESSAGE_UPDATE.js +16 -0
  140. package/src/client/websocket/handlers/PRESENCE_UPDATE.js +5 -0
  141. package/src/client/websocket/handlers/READY.js +120 -0
  142. package/src/client/websocket/handlers/RELATIONSHIP_ADD.js +19 -0
  143. package/src/client/websocket/handlers/RELATIONSHIP_REMOVE.js +17 -0
  144. package/src/client/websocket/handlers/RELATIONSHIP_UPDATE.js +41 -0
  145. package/src/client/websocket/handlers/RESUMED.js +14 -0
  146. package/src/client/websocket/handlers/STAGE_INSTANCE_CREATE.js +5 -0
  147. package/src/client/websocket/handlers/STAGE_INSTANCE_DELETE.js +5 -0
  148. package/src/client/websocket/handlers/STAGE_INSTANCE_UPDATE.js +5 -0
  149. package/src/client/websocket/handlers/THREAD_CREATE.js +5 -0
  150. package/src/client/websocket/handlers/THREAD_DELETE.js +5 -0
  151. package/src/client/websocket/handlers/THREAD_LIST_SYNC.js +5 -0
  152. package/src/client/websocket/handlers/THREAD_MEMBERS_UPDATE.js +5 -0
  153. package/src/client/websocket/handlers/THREAD_MEMBER_UPDATE.js +5 -0
  154. package/src/client/websocket/handlers/THREAD_UPDATE.js +16 -0
  155. package/src/client/websocket/handlers/TYPING_START.js +5 -0
  156. package/src/client/websocket/handlers/USER_GUILD_SETTINGS_UPDATE.js +6 -0
  157. package/src/client/websocket/handlers/USER_NOTE_UPDATE.js +5 -0
  158. package/src/client/websocket/handlers/USER_REQUIRED_ACTION_UPDATE.js +78 -0
  159. package/src/client/websocket/handlers/USER_SETTINGS_UPDATE.js +5 -0
  160. package/src/client/websocket/handlers/USER_UPDATE.js +5 -0
  161. package/src/client/websocket/handlers/VOICE_CHANNEL_STATUS_UPDATE.js +12 -0
  162. package/src/client/websocket/handlers/VOICE_SERVER_UPDATE.js +6 -0
  163. package/src/client/websocket/handlers/VOICE_STATE_UPDATE.js +5 -0
  164. package/src/client/websocket/handlers/WEBHOOKS_UPDATE.js +5 -0
  165. package/src/client/websocket/handlers/index.js +83 -0
  166. package/src/errors/DJSError.js +61 -0
  167. package/src/errors/Messages.js +208 -0
  168. package/src/errors/index.js +4 -0
  169. package/src/index.js +159 -0
  170. package/src/managers/ApplicationCommandManager.js +264 -0
  171. package/src/managers/ApplicationCommandPermissionsManager.js +417 -0
  172. package/src/managers/AutoModerationRuleManager.js +296 -0
  173. package/src/managers/BaseGuildEmojiManager.js +80 -0
  174. package/src/managers/BaseManager.js +19 -0
  175. package/src/managers/BillingManager.js +66 -0
  176. package/src/managers/CachedManager.js +71 -0
  177. package/src/managers/ChannelManager.js +138 -0
  178. package/src/managers/ClientUserSettingManager.js +372 -0
  179. package/src/managers/DataManager.js +61 -0
  180. package/src/managers/GuildBanManager.js +204 -0
  181. package/src/managers/GuildChannelManager.js +488 -0
  182. package/src/managers/GuildEmojiManager.js +171 -0
  183. package/src/managers/GuildEmojiRoleManager.js +118 -0
  184. package/src/managers/GuildForumThreadManager.js +108 -0
  185. package/src/managers/GuildInviteManager.js +213 -0
  186. package/src/managers/GuildManager.js +304 -0
  187. package/src/managers/GuildMemberManager.js +597 -0
  188. package/src/managers/GuildMemberRoleManager.js +191 -0
  189. package/src/managers/GuildScheduledEventManager.js +296 -0
  190. package/src/managers/GuildSettingManager.js +155 -0
  191. package/src/managers/GuildStickerManager.js +179 -0
  192. package/src/managers/GuildTextThreadManager.js +98 -0
  193. package/src/managers/InteractionManager.js +39 -0
  194. package/src/managers/MessageManager.js +391 -0
  195. package/src/managers/PermissionOverwriteManager.js +166 -0
  196. package/src/managers/PresenceManager.js +58 -0
  197. package/src/managers/ReactionManager.js +67 -0
  198. package/src/managers/ReactionUserManager.js +71 -0
  199. package/src/managers/RelationshipManager.js +265 -0
  200. package/src/managers/RoleManager.js +352 -0
  201. package/src/managers/StageInstanceManager.js +162 -0
  202. package/src/managers/ThreadManager.js +174 -0
  203. package/src/managers/ThreadMemberManager.js +186 -0
  204. package/src/managers/UserManager.js +146 -0
  205. package/src/managers/UserNoteManager.js +53 -0
  206. package/src/managers/VoiceStateManager.js +37 -0
  207. package/src/rest/APIRequest.js +159 -0
  208. package/src/rest/APIRouter.js +53 -0
  209. package/src/rest/DiscordAPIError.js +104 -0
  210. package/src/rest/HTTPError.js +62 -0
  211. package/src/rest/RESTManager.js +62 -0
  212. package/src/rest/RateLimitError.js +55 -0
  213. package/src/rest/RequestHandler.js +444 -0
  214. package/src/sharding/Shard.js +443 -0
  215. package/src/sharding/ShardClientUtil.js +275 -0
  216. package/src/sharding/ShardingManager.js +318 -0
  217. package/src/structures/AnonymousGuild.js +98 -0
  218. package/src/structures/ApplicationCommand.js +593 -0
  219. package/src/structures/ApplicationRoleConnectionMetadata.js +48 -0
  220. package/src/structures/AutoModerationActionExecution.js +89 -0
  221. package/src/structures/AutoModerationRule.js +294 -0
  222. package/src/structures/AutocompleteInteraction.js +107 -0
  223. package/src/structures/Base.js +43 -0
  224. package/src/structures/BaseCommandInteraction.js +211 -0
  225. package/src/structures/BaseGuild.js +116 -0
  226. package/src/structures/BaseGuildEmoji.js +56 -0
  227. package/src/structures/BaseGuildTextChannel.js +191 -0
  228. package/src/structures/BaseGuildVoiceChannel.js +241 -0
  229. package/src/structures/BaseMessageComponent.js +114 -0
  230. package/src/structures/ButtonInteraction.js +11 -0
  231. package/src/structures/CallState.js +63 -0
  232. package/src/structures/CategoryChannel.js +85 -0
  233. package/src/structures/Channel.js +270 -0
  234. package/src/structures/ClientPresence.js +77 -0
  235. package/src/structures/ClientUser.js +450 -0
  236. package/src/structures/CommandInteraction.js +41 -0
  237. package/src/structures/CommandInteractionOptionResolver.js +276 -0
  238. package/src/structures/ContextMenuInteraction.js +65 -0
  239. package/src/structures/DMChannel.js +217 -0
  240. package/src/structures/DirectoryChannel.js +20 -0
  241. package/src/structures/Emoji.js +148 -0
  242. package/src/structures/ForumChannel.js +261 -0
  243. package/src/structures/GroupDMChannel.js +387 -0
  244. package/src/structures/Guild.js +1608 -0
  245. package/src/structures/GuildAuditLogs.js +729 -0
  246. package/src/structures/GuildBan.js +59 -0
  247. package/src/structures/GuildBoost.js +108 -0
  248. package/src/structures/GuildChannel.js +468 -0
  249. package/src/structures/GuildEmoji.js +161 -0
  250. package/src/structures/GuildMember.js +568 -0
  251. package/src/structures/GuildPreview.js +191 -0
  252. package/src/structures/GuildPreviewEmoji.js +27 -0
  253. package/src/structures/GuildScheduledEvent.js +441 -0
  254. package/src/structures/GuildTemplate.js +236 -0
  255. package/src/structures/Integration.js +188 -0
  256. package/src/structures/IntegrationApplication.js +96 -0
  257. package/src/structures/Interaction.js +290 -0
  258. package/src/structures/InteractionCollector.js +248 -0
  259. package/src/structures/InteractionWebhook.js +43 -0
  260. package/src/structures/Invite.js +358 -0
  261. package/src/structures/InviteGuild.js +23 -0
  262. package/src/structures/InviteStageInstance.js +86 -0
  263. package/src/structures/Message.js +1227 -0
  264. package/src/structures/MessageActionRow.js +103 -0
  265. package/src/structures/MessageAttachment.js +204 -0
  266. package/src/structures/MessageButton.js +165 -0
  267. package/src/structures/MessageCollector.js +146 -0
  268. package/src/structures/MessageComponentInteraction.js +120 -0
  269. package/src/structures/MessageContextMenuInteraction.js +20 -0
  270. package/src/structures/MessageEmbed.js +586 -0
  271. package/src/structures/MessageMentions.js +273 -0
  272. package/src/structures/MessagePayload.js +318 -0
  273. package/src/structures/MessagePoll.js +238 -0
  274. package/src/structures/MessageReaction.js +171 -0
  275. package/src/structures/MessageSelectMenu.js +140 -0
  276. package/src/structures/Modal.js +161 -0
  277. package/src/structures/ModalSubmitFieldsResolver.js +53 -0
  278. package/src/structures/ModalSubmitInteraction.js +119 -0
  279. package/src/structures/NewsChannel.js +32 -0
  280. package/src/structures/OAuth2Guild.js +28 -0
  281. package/src/structures/PermissionOverwrites.js +196 -0
  282. package/src/structures/Presence.js +1131 -0
  283. package/src/structures/ReactionCollector.js +229 -0
  284. package/src/structures/ReactionEmoji.js +31 -0
  285. package/src/structures/Role.js +531 -0
  286. package/src/structures/SelectMenuInteraction.js +21 -0
  287. package/src/structures/StageChannel.js +104 -0
  288. package/src/structures/StageInstance.js +208 -0
  289. package/src/structures/Sticker.js +310 -0
  290. package/src/structures/StickerPack.js +95 -0
  291. package/src/structures/StoreChannel.js +56 -0
  292. package/src/structures/Team.js +118 -0
  293. package/src/structures/TeamMember.js +71 -0
  294. package/src/structures/TextChannel.js +33 -0
  295. package/src/structures/TextInputComponent.js +131 -0
  296. package/src/structures/ThreadChannel.js +607 -0
  297. package/src/structures/ThreadMember.js +105 -0
  298. package/src/structures/Typing.js +74 -0
  299. package/src/structures/User.js +543 -0
  300. package/src/structures/UserContextMenuInteraction.js +29 -0
  301. package/src/structures/VoiceChannel.js +110 -0
  302. package/src/structures/VoiceRegion.js +53 -0
  303. package/src/structures/VoiceState.js +345 -0
  304. package/src/structures/WebEmbed.js +373 -0
  305. package/src/structures/Webhook.js +467 -0
  306. package/src/structures/WelcomeChannel.js +60 -0
  307. package/src/structures/WelcomeScreen.js +48 -0
  308. package/src/structures/Widget.js +87 -0
  309. package/src/structures/WidgetMember.js +99 -0
  310. package/src/structures/interfaces/Application.js +313 -0
  311. package/src/structures/interfaces/Collector.js +300 -0
  312. package/src/structures/interfaces/InteractionResponses.js +313 -0
  313. package/src/structures/interfaces/TextBasedChannel.js +719 -0
  314. package/src/util/ActivityFlags.js +44 -0
  315. package/src/util/ApplicationFlags.js +76 -0
  316. package/src/util/AttachmentFlags.js +38 -0
  317. package/src/util/BitField.js +170 -0
  318. package/src/util/ChannelFlags.js +45 -0
  319. package/src/util/Constants.js +1815 -0
  320. package/src/util/DataResolver.js +145 -0
  321. package/src/util/Formatters.js +228 -0
  322. package/src/util/GuildMemberFlags.js +43 -0
  323. package/src/util/Intents.js +74 -0
  324. package/src/util/InviteFlags.js +29 -0
  325. package/src/util/LimitedCollection.js +131 -0
  326. package/src/util/MessageFlags.js +54 -0
  327. package/src/util/Options.js +336 -0
  328. package/src/util/Permissions.js +202 -0
  329. package/src/util/PremiumUsageFlags.js +31 -0
  330. package/src/util/PurchasedFlags.js +33 -0
  331. package/src/util/RemoteAuth.js +382 -0
  332. package/src/util/RoleFlags.js +37 -0
  333. package/src/util/SnowflakeUtil.js +92 -0
  334. package/src/util/Speaking.js +33 -0
  335. package/src/util/Sweepers.js +466 -0
  336. package/src/util/SystemChannelFlags.js +55 -0
  337. package/src/util/ThreadMemberFlags.js +30 -0
  338. package/src/util/UserFlags.js +104 -0
  339. package/src/util/Util.js +889 -0
  340. package/typings/enums.d.ts +297 -0
  341. package/typings/index.d.ts +7670 -0
  342. package/typings/index.test-d.ts +0 -0
  343. package/typings/rawDataTypes.d.ts +342 -0
@@ -0,0 +1,120 @@
1
+ 'use strict';
2
+
3
+ /*
4
+ Credit: https://github.com/dank074/Discord-video-stream
5
+ The use of video streaming in this library is an incomplete implementation with many bugs, primarily aimed at lazy users.
6
+ The video streaming features in this library are sourced from https://github.com/dank074/Discord-video-stream.
7
+
8
+ Please use the @dank074/discord-video-stream library to access all advanced and professional features,
9
+ along with comprehensive support. I will not actively fix bugs related to streaming and encourage everyone to
10
+ use https://github.com/dank074/Discord-video-stream for stable and smooth streaming.
11
+
12
+ To reiterate: This is an incomplete implementation of the library https://github.com/dank074/Discord-video-stream.
13
+
14
+ Thanks to dank074 and longnguyen2004 for implementing new codecs (H264, H265).
15
+ Thanks to mrjvs for discovering how Discord transmits data and the VP8 codec.
16
+
17
+ Please use the @dank074/discord-video-stream library for the best support.
18
+ */
19
+
20
+ const { Buffer } = require('buffer');
21
+ const VideoDispatcher = require('./VideoDispatcher');
22
+ const { H264Helpers, H265Helpers } = require('../player/processing/AnnexBNalSplitter');
23
+
24
+ class AnnexBDispatcher extends VideoDispatcher {
25
+ constructor(player, highWaterMark = 12, streams, fps, nalFunctions) {
26
+ super(player, highWaterMark, streams, fps);
27
+ this._nalFunctions = nalFunctions;
28
+ }
29
+
30
+ codecCallback(frame) {
31
+ let accessUnit = frame;
32
+ let offset = 0;
33
+
34
+ // Extract NALUs from the access unit
35
+ while (offset < accessUnit.length) {
36
+ const naluSize = accessUnit.readUInt32BE(offset);
37
+ offset += 4;
38
+ const nalu = accessUnit.subarray(offset, offset + naluSize);
39
+ const isLastNal = offset + naluSize >= accessUnit.length;
40
+ if (nalu.length <= this.mtu) {
41
+ // If NALU size is within MTU, send it directly
42
+ this._playChunk(Buffer.concat([this.createHeaderExtension(), nalu]), isLastNal);
43
+ } else {
44
+ // If NALU size exceeds MTU, fragment it
45
+ const [naluHeader, naluData] = this._nalFunctions.splitHeader(nalu);
46
+ const dataFragments = this.partitionVideoData(naluData);
47
+
48
+ for (let fragmentIndex = 0; fragmentIndex < dataFragments.length; fragmentIndex++) {
49
+ const data = dataFragments[fragmentIndex];
50
+ const isFirstPacket = fragmentIndex === 0;
51
+ const isFinalPacket = fragmentIndex === dataFragments.length - 1;
52
+
53
+ this._playChunk(
54
+ Buffer.concat([
55
+ this.createHeaderExtension(),
56
+ this.makeFragmentationUnitHeader(isFirstPacket, isFinalPacket, naluHeader),
57
+ data,
58
+ ]),
59
+ isLastNal && isFinalPacket,
60
+ );
61
+ }
62
+ }
63
+ offset += naluSize;
64
+ }
65
+ }
66
+ }
67
+
68
+ class H264Dispatcher extends AnnexBDispatcher {
69
+ constructor(player, highWaterMark = 12, streams, fps) {
70
+ super(player, highWaterMark, streams, fps, H264Helpers);
71
+ }
72
+
73
+ makeFragmentationUnitHeader(isFirstPacket, isLastPacket, naluHeader) {
74
+ const nal0 = naluHeader[0];
75
+ const fuPayloadHeader = Buffer.alloc(2);
76
+ const nalType = H264Helpers.getUnitType(naluHeader);
77
+ const fnri = nal0 & 0xe0;
78
+
79
+ fuPayloadHeader[0] = 0x1c | fnri;
80
+
81
+ if (isFirstPacket) {
82
+ fuPayloadHeader[1] = 0x80 | nalType;
83
+ } else if (isLastPacket) {
84
+ fuPayloadHeader[1] = 0x40 | nalType;
85
+ } else {
86
+ fuPayloadHeader[1] = nalType;
87
+ }
88
+
89
+ return fuPayloadHeader;
90
+ }
91
+ }
92
+
93
+ class H265Dispatcher extends AnnexBDispatcher {
94
+ constructor(player, highWaterMark = 12, streams, fps) {
95
+ super(player, highWaterMark, streams, fps, H265Helpers);
96
+ }
97
+
98
+ makeFragmentationUnitHeader(isFirstPacket, isLastPacket, naluHeader) {
99
+ const fuIndicatorHeader = Buffer.allocUnsafe(3);
100
+ naluHeader.copy(fuIndicatorHeader);
101
+ const nalType = H265Helpers.getUnitType(naluHeader);
102
+
103
+ fuIndicatorHeader[0] = (fuIndicatorHeader[0] & 0b10000001) | (49 << 1);
104
+
105
+ if (isFirstPacket) {
106
+ fuIndicatorHeader[2] = 0x80 | nalType;
107
+ } else if (isLastPacket) {
108
+ fuIndicatorHeader[2] = 0x40 | nalType;
109
+ } else {
110
+ fuIndicatorHeader[2] = nalType;
111
+ }
112
+
113
+ return fuIndicatorHeader;
114
+ }
115
+ }
116
+
117
+ module.exports = {
118
+ H264Dispatcher,
119
+ H265Dispatcher,
120
+ };
@@ -0,0 +1,115 @@
1
+ 'use strict';
2
+
3
+ const BaseDispatcher = require('./BaseDispatcher');
4
+ const Silence = require('../util/Silence');
5
+ const VolumeInterface = require('../util/VolumeInterface');
6
+
7
+ /**
8
+ * @external WritableStream
9
+ * @see {@link https://nodejs.org/api/stream.html#stream_class_stream_writable}
10
+ */
11
+
12
+ /**
13
+ * The class that sends voice packet data to the voice connection.
14
+ * ```js
15
+ * // Obtained using:
16
+ * client.voice.joinChannel(channel).then(connection => {
17
+ * // You can play a file or a stream here:
18
+ * const dispatcher = connection.playAudio('/home/hydrabolt/audio.mp3');
19
+ * });
20
+ * ```
21
+ * @implements {VolumeInterface}
22
+ * @extends {BaseDispatcher}
23
+ */
24
+ class AudioDispatcher extends BaseDispatcher {
25
+ constructor(player, { seek = 0, volume = 1, fec, plp, bitrate = 96, highWaterMark = 12 } = {}, streams) {
26
+ const streamOptions = { seek, volume, fec, plp, bitrate, highWaterMark };
27
+ super(player, highWaterMark, 120, false, streams);
28
+
29
+ this.streamOptions = streamOptions;
30
+
31
+ this.streams.silence = new Silence();
32
+
33
+ this.setVolume(volume);
34
+ this.setBitrate(bitrate);
35
+ if (typeof fec !== 'undefined') this.setFEC(fec);
36
+ if (typeof plp !== 'undefined') this.setPLP(plp);
37
+ }
38
+
39
+ /**
40
+ * Set the bitrate of the current Opus encoder if using a compatible Opus stream.
41
+ * @param {number} value New bitrate, in kbps
42
+ * If set to 'auto', the voice channel's bitrate will be used
43
+ * @returns {boolean} true if the bitrate has been successfully changed.
44
+ */
45
+ setBitrate(value) {
46
+ if (!value || !this.bitrateEditable) return false;
47
+ const bitrate = value === 'auto' ? this.player.voiceConnection.channel.bitrate : value;
48
+ this.streams.opus.setBitrate(bitrate * 1000);
49
+ return true;
50
+ }
51
+
52
+ /**
53
+ * Sets the expected packet loss percentage if using a compatible Opus stream.
54
+ * @param {number} value between 0 and 1
55
+ * @returns {boolean} Returns true if it was successfully set.
56
+ */
57
+ setPLP(value) {
58
+ if (!this.bitrateEditable) return false;
59
+ this.streams.opus.setPLP(value);
60
+ return true;
61
+ }
62
+
63
+ /**
64
+ * Enables or disables forward error correction if using a compatible Opus stream.
65
+ * @param {boolean} enabled true to enable
66
+ * @returns {boolean} Returns true if it was successfully set.
67
+ */
68
+ setFEC(enabled) {
69
+ if (!this.bitrateEditable) return false;
70
+ this.streams.opus.setFEC(enabled);
71
+ return true;
72
+ }
73
+
74
+ get volumeEditable() {
75
+ return Boolean(this.streams.volume);
76
+ }
77
+
78
+ /**
79
+ * Whether or not the Opus bitrate of this stream is editable
80
+ * @type {boolean}
81
+ * @readonly
82
+ */
83
+ get bitrateEditable() {
84
+ return this.streams.opus && this.streams.opus.setBitrate;
85
+ }
86
+
87
+ // Volume
88
+ get volume() {
89
+ return this.streams.volume ? this.streams.volume.volume : 1;
90
+ }
91
+
92
+ setVolume(value) {
93
+ if (!this.streams.volume) return false;
94
+ /**
95
+ * Emitted when the volume of this dispatcher changes.
96
+ * @event AudioDispatcher#volumeChange
97
+ * @param {number} oldVolume The old volume of this dispatcher
98
+ * @param {number} newVolume The new volume of this dispatcher
99
+ */
100
+ this.emit('volumeChange', this.volume, value);
101
+ this.streams.volume.setVolume(value);
102
+ return true;
103
+ }
104
+
105
+ // Volume stubs for docs
106
+ /* eslint-disable no-empty-function*/
107
+ get volumeDecibels() {}
108
+ get volumeLogarithmic() {}
109
+ setVolumeDecibels() {}
110
+ setVolumeLogarithmic() {}
111
+ }
112
+
113
+ VolumeInterface.applyToClass(AudioDispatcher);
114
+
115
+ module.exports = AudioDispatcher;
@@ -0,0 +1,405 @@
1
+ 'use strict';
2
+
3
+ const { Buffer } = require('node:buffer');
4
+ const { setTimeout } = require('node:timers');
5
+ const { Writable } = require('stream');
6
+ const find = require('find-process');
7
+ const kill = require('tree-kill');
8
+ const secretbox = require('../util/Secretbox');
9
+
10
+ const CHANNELS = 2;
11
+
12
+ const MAX_NONCE_SIZE = 2 ** 32 - 1;
13
+ const nonce = Buffer.alloc(24);
14
+
15
+ /**
16
+ * @external WritableStream
17
+ * @see {@link https://nodejs.org/api/stream.html#stream_class_stream_writable}
18
+ */
19
+
20
+ /**
21
+ * @extends {Writable}
22
+ */
23
+ class BaseDispatcher extends Writable {
24
+ constructor(player, highWaterMark = 12, payloadType, extensionEnabled, streams = {}) {
25
+ super({
26
+ highWaterMark,
27
+ });
28
+ this.streams = streams;
29
+ /**
30
+ * The Audio Player that controls this dispatcher
31
+ * @type {MediaPlayer}
32
+ */
33
+ this.player = player;
34
+ this.payloadType = payloadType;
35
+ this.extensionEnabled = extensionEnabled;
36
+
37
+ this._nonce = 0;
38
+ this._nonceBuffer = Buffer.alloc(24);
39
+
40
+ /**
41
+ * The time that the stream was paused at (null if not paused)
42
+ * @type {?number}
43
+ */
44
+ this.pausedSince = null;
45
+ this._writeCallback = null;
46
+
47
+ this._pausedTime = 0;
48
+ this._silentPausedTime = 0;
49
+
50
+ this.count = 0;
51
+ this.sequence = 0;
52
+ this.timestamp = 0;
53
+
54
+ /**
55
+ * Video FPS
56
+ * @type {number}
57
+ */
58
+ this.fps = 0;
59
+
60
+ this.mtu = 1200;
61
+
62
+ const streamError = (type, err) => {
63
+ /**
64
+ * Emitted when the dispatcher encounters an error.
65
+ * @event BaseDispatcher#error
66
+ */
67
+ if (type && err) {
68
+ err.message = `${type} stream: ${err.message}`;
69
+ this.emit(this.player.dispatcher === this ? 'error' : 'debug', err);
70
+ }
71
+ this.destroy();
72
+ };
73
+
74
+ this.on('error', () => streamError());
75
+ if (this.streams.input) this.streams.input.on('error', err => streamError('input', err));
76
+ if (this.streams.ffmpeg) this.streams.ffmpeg.on('error', err => streamError('ffmpeg', err));
77
+ if (this.streams.opus) this.streams.opus.on('error', err => streamError('opus', err));
78
+ if (this.streams.volume) this.streams.volume.on('error', err => streamError('volume', err));
79
+
80
+ this.on('finish', () => {
81
+ this._cleanup();
82
+ this._setSpeaking(0);
83
+ this._setVideoStatus(false);
84
+ this._setStreamStatus(true);
85
+ });
86
+ }
87
+
88
+ get TIMESTAMP_INC() {
89
+ return this.extensionEnabled ? 90000 / this.fps : 480 * CHANNELS;
90
+ }
91
+
92
+ get FRAME_LENGTH() {
93
+ return this.extensionEnabled ? 1000 / this.fps : 20;
94
+ }
95
+
96
+ partitionVideoData(data) {
97
+ const out = [];
98
+ const dataLength = data.length;
99
+
100
+ for (let i = 0; i < dataLength; i += this.mtu) {
101
+ out.push(data.slice(i, i + this.mtu));
102
+ }
103
+
104
+ return out;
105
+ }
106
+
107
+ getNewSequence() {
108
+ const currentSeq = this.sequence;
109
+ this.sequence++;
110
+ if (this.sequence >= 2 ** 16) this.sequence = 0;
111
+ return currentSeq;
112
+ }
113
+
114
+ _write(chunk, enc, done) {
115
+ if (!this.startTime) {
116
+ /**
117
+ * Emitted once the stream has started to play.
118
+ * @event BaseDispatcher#start
119
+ */
120
+ this.emit('start');
121
+ this.startTime = performance.now();
122
+ }
123
+ if (this.extensionEnabled) {
124
+ this.codecCallback(chunk);
125
+ } else {
126
+ this._playChunk(chunk);
127
+ }
128
+ this._step(done);
129
+ }
130
+
131
+ _destroy(err, cb) {
132
+ this._cleanup();
133
+ super._destroy(err, cb);
134
+ }
135
+
136
+ _cleanup() {
137
+ if (this.player.dispatcher === this) this.player.dispatcher = null;
138
+ const { streams } = this;
139
+ if (streams.opus) streams.opus.destroy();
140
+ if (streams.ffmpeg?.process) {
141
+ const ffmpegPid = streams.ffmpeg.process.pid; // But it is ppid ;-;
142
+ const args = streams.ffmpeg.process.spawnargs.slice(1).join(' '); // Skip ffmpeg
143
+ find('name', 'ffmpeg', true).then(list => {
144
+ let process = list.find(o => o.pid === ffmpegPid || o.ppid === ffmpegPid || o.cmd.includes(args));
145
+ if (process) {
146
+ kill(process.pid);
147
+ }
148
+ });
149
+ streams.ffmpeg.destroy();
150
+ }
151
+ }
152
+
153
+ /**
154
+ * Pauses playback
155
+ * @param {boolean} [silence=false] Whether to play silence while paused to prevent audio glitches
156
+ */
157
+ pause(silence = false) {
158
+ if (this.paused) return;
159
+ if (this.streams.opus) this.streams.opus.unpipe(this); // Audio
160
+ if (this.streams.video) {
161
+ this.streams.ffmpeg.pause();
162
+ this.streams.video.unpipe(this);
163
+ }
164
+ if (!this.extensionEnabled) {
165
+ // Audio
166
+ if (silence) {
167
+ this.streams.silence.pipe(this);
168
+ this._silence = true;
169
+ } else {
170
+ this._setSpeaking(0);
171
+ }
172
+ }
173
+ this.pausedSince = performance.now();
174
+ }
175
+
176
+ /**
177
+ * Whether or not playback is paused
178
+ * @type {boolean}
179
+ * @readonly
180
+ */
181
+ get paused() {
182
+ return Boolean(this.pausedSince);
183
+ }
184
+
185
+ /**
186
+ * Total time that this dispatcher has been paused in milliseconds
187
+ * @type {number}
188
+ * @readonly
189
+ */
190
+ get pausedTime() {
191
+ return this._silentPausedTime + this._pausedTime + (this.paused ? performance.now() - this.pausedSince : 0);
192
+ }
193
+
194
+ /**
195
+ * Resumes playback
196
+ */
197
+ resume() {
198
+ if (!this.pausedSince) return;
199
+ if (!this.extensionEnabled) this.streams.silence.unpipe(this);
200
+ if (this.streams.opus) this.streams.opus.pipe(this);
201
+ if (this.streams.video) {
202
+ this.streams.ffmpeg.resume();
203
+ this.streams.video.pipe(this);
204
+ }
205
+ if (this._silence) {
206
+ this._silentPausedTime += performance.now() - this.pausedSince;
207
+ this._silence = false;
208
+ } else {
209
+ this._pausedTime += performance.now() - this.pausedSince;
210
+ }
211
+ this.pausedSince = null;
212
+ if (typeof this._writeCallback === 'function') this._writeCallback();
213
+ }
214
+
215
+ /**
216
+ * The time (in milliseconds) that the dispatcher has been playing audio for, taking into account skips and pauses
217
+ * @type {number}
218
+ * @readonly
219
+ */
220
+ get totalStreamTime() {
221
+ return performance.now() - this.startTime;
222
+ }
223
+
224
+ _step(done) {
225
+ this._writeCallback = () => {
226
+ this._writeCallback = null;
227
+ done();
228
+ };
229
+ const next = (this.count + 1) * this.FRAME_LENGTH - (performance.now() - this.startTime - this._pausedTime);
230
+ setTimeout(() => {
231
+ if ((!this.pausedSince || this._silence) && this._writeCallback) this._writeCallback();
232
+ }, next).unref();
233
+ this.timestamp += this.TIMESTAMP_INC;
234
+ if (this.timestamp >= 2 ** 32) this.timestamp = 0;
235
+ this.count++;
236
+ }
237
+
238
+ _final(callback) {
239
+ this._writeCallback = null;
240
+ callback();
241
+ }
242
+
243
+ _playChunk(chunk, isLastPacket) {
244
+ if (
245
+ (this.player.dispatcher !== this && this.player.videoDispatcher !== this) ||
246
+ !this.player.voiceConnection.authentication.secret_key
247
+ ) {
248
+ return;
249
+ }
250
+ this[this.extensionEnabled ? '_sendVideoPacket' : '_sendPacket'](this._createPacket(chunk, isLastPacket));
251
+ }
252
+
253
+ /**
254
+ * Creates a single extension of type playout-delay
255
+ * Discord seems to send this extension on every video packet
256
+ * @see https://webrtc.googlesource.com/src/+/refs/heads/main/docs/native-code/rtp-hdrext/playout-delay
257
+ * @returns {Buffer} playout-delay extension
258
+ * Buffer <be de 00 01 51 00 00 00>
259
+ * @private
260
+ */
261
+ createHeaderExtension() {
262
+ const extensions = [{ id: 5, len: 2, val: 0 }];
263
+ /**
264
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
265
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
266
+ | defined by profile | length |
267
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
268
+ */
269
+ const profile = Buffer.alloc(4);
270
+ profile[0] = 0xbe;
271
+ profile[1] = 0xde;
272
+ profile.writeInt16BE(extensions.length, 2); // Extension count
273
+ const extensionsData = [];
274
+ for (let ext of extensions) {
275
+ /**
276
+ * EXTENSION DATA - each extension payload is 32 bits
277
+ */
278
+ const data = Buffer.alloc(4);
279
+ /**
280
+ * 0 1 2 3 4 5 6 7
281
+ +-+-+-+-+-+-+-+-+
282
+ | ID | len |
283
+ +-+-+-+-+-+-+-+-+
284
+
285
+ where len = actual length - 1
286
+ */
287
+ data[0] = (ext.id & 0b00001111) << 4;
288
+ data[0] |= (ext.len - 1) & 0b00001111;
289
+ /** Specific to type playout-delay
290
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4
291
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
292
+ | MIN delay | MAX delay |
293
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
294
+ */
295
+ data.writeUIntBE(ext.val, 1, 2); // Not quite but its 0 anyway
296
+ extensionsData.push(data);
297
+ }
298
+ return Buffer.concat([profile, ...extensionsData]);
299
+ }
300
+
301
+ _encrypt(buffer) {
302
+ const { secret_key, mode } = this.player.voiceConnection.authentication;
303
+ if (mode === 'xsalsa20_poly1305_lite') {
304
+ this._nonce++;
305
+ if (this._nonce > MAX_NONCE_SIZE) this._nonce = 0;
306
+ this._nonceBuffer.writeUInt32BE(this._nonce, 0);
307
+ return [secretbox.methods.close(buffer, this._nonceBuffer, secret_key), this._nonceBuffer.slice(0, 4)];
308
+ } else if (mode === 'xsalsa20_poly1305_suffix') {
309
+ const random = secretbox.methods.random(24);
310
+ return [secretbox.methods.close(buffer, random, secret_key), random];
311
+ } else {
312
+ return [secretbox.methods.close(buffer, nonce, secret_key)];
313
+ }
314
+ }
315
+
316
+ _createPacket(buffer, isLastPacket = false) {
317
+ // Header
318
+ const packetBuffer = Buffer.alloc(12);
319
+ packetBuffer[0] = this.extensionEnabled ? 0x90 : 0x80; // 0b10000000 | ((this.extensionEnabled ? 1 : 0) << 4);
320
+ packetBuffer[1] = this.payloadType;
321
+
322
+ if (this.extensionEnabled) {
323
+ if (isLastPacket) {
324
+ packetBuffer[1] |= 0x80;
325
+ }
326
+ }
327
+
328
+ packetBuffer.writeUIntBE(this.getNewSequence(), 2, 2);
329
+ packetBuffer.writeUIntBE(this.timestamp, 4, 4);
330
+ packetBuffer.writeUIntBE(this.player.voiceConnection.authentication.ssrc + this.extensionEnabled, 8, 4);
331
+
332
+ packetBuffer.copy(nonce, 0, 0, 12);
333
+
334
+ return Buffer.concat([packetBuffer, ...this._encrypt(buffer)]);
335
+ }
336
+
337
+ _sendPacket(packet) {
338
+ /**
339
+ * Emitted whenever the dispatcher has debug information.
340
+ * @event BaseDispatcher#debug
341
+ * @param {string} info The debug info
342
+ */
343
+ this._setSpeaking(1);
344
+ if (!this.player.voiceConnection.sockets.udp) {
345
+ this.emit('debug', 'Failed to send a packet - no UDP socket');
346
+ return;
347
+ }
348
+ this.player.voiceConnection.sockets.udp.send(packet).catch(e => {
349
+ this._setSpeaking(0);
350
+ this.emit('debug', `Failed to send a packet - ${e}`);
351
+ });
352
+ }
353
+
354
+ _sendVideoPacket(packet) {
355
+ this._setVideoStatus(true);
356
+ this._setStreamStatus(false);
357
+ if (!this.player.voiceConnection.sockets.udp) {
358
+ this.emit('debug', 'Failed to send a video packet - no UDP socket');
359
+ return;
360
+ }
361
+ this.player.voiceConnection.sockets.udp.send(packet).catch(e => {
362
+ this._setVideoStatus(false);
363
+ this._setStreamStatus(true);
364
+ this.emit('debug', `Failed to send a video packet - ${e}`);
365
+ });
366
+ }
367
+
368
+ _setSpeaking(value) {
369
+ if (typeof this.player.voiceConnection !== 'undefined') {
370
+ this.player.voiceConnection.setSpeaking(value);
371
+ }
372
+ /**
373
+ * Emitted when the dispatcher starts/stops speaking.
374
+ * @event AudioDispatcher#speaking
375
+ * @param {boolean} value Whether or not the dispatcher is speaking
376
+ */
377
+ this.emit('speaking', value);
378
+ }
379
+
380
+ _setVideoStatus(value) {
381
+ if (typeof this.player.voiceConnection !== 'undefined') {
382
+ this.player.voiceConnection.setVideoStatus(value);
383
+ }
384
+ /**
385
+ * Emitted when the dispatcher starts/stops video.
386
+ * @event VideoDispatcher#videoStatus
387
+ * @param {boolean} value Whether or not the dispatcher is enable video
388
+ */
389
+ this.emit('videoStatus', value);
390
+ }
391
+
392
+ _setStreamStatus(value) {
393
+ if (typeof this.player.voiceConnection?.sendScreenshareState !== 'undefined') {
394
+ this.player.voiceConnection.sendScreenshareState(value);
395
+ }
396
+ /**
397
+ * Emitted when the dispatcher starts/stops video.
398
+ * @event VideoDispatcher#streamStatus
399
+ * @param {boolean} isPaused Whether or not the dispatcher is pause video
400
+ */
401
+ this.emit('streamStatus', value);
402
+ }
403
+ }
404
+
405
+ module.exports = BaseDispatcher;
@@ -0,0 +1,52 @@
1
+ 'use strict';
2
+
3
+ /*
4
+ Credit: https://github.com/dank074/Discord-video-stream
5
+ The use of video streaming in this library is an incomplete implementation with many bugs, primarily aimed at lazy users.
6
+ The video streaming features in this library are sourced from https://github.com/dank074/Discord-video-stream.
7
+
8
+ Please use the @dank074/discord-video-stream library to access all advanced and professional features,
9
+ along with comprehensive support. I will not actively fix bugs related to streaming and encourage everyone to
10
+ use https://github.com/dank074/Discord-video-stream for stable and smooth streaming.
11
+
12
+ To reiterate: This is an incomplete implementation of the library https://github.com/dank074/Discord-video-stream.
13
+
14
+ Thanks to dank074 and longnguyen2004 for implementing new codecs (H264, H265).
15
+ Thanks to mrjvs for discovering how Discord transmits data and the VP8 codec.
16
+
17
+ Please use the @dank074/discord-video-stream library for the best support.
18
+ */
19
+
20
+ const { Buffer } = require('node:buffer');
21
+ const VideoDispatcher = require('./VideoDispatcher');
22
+
23
+ class VP8Dispatcher extends VideoDispatcher {
24
+ constructor(player, highWaterMark = 12, streams, fps) {
25
+ super(player, highWaterMark, streams, fps);
26
+ }
27
+
28
+ makeChunk(buffer, isFirstFrame) {
29
+ // Make frame
30
+ const headerExtensionBuf = this.createHeaderExtension();
31
+ // Vp8 payload descriptor
32
+ const payloadDescriptorBuf = Buffer.alloc(2);
33
+ payloadDescriptorBuf[0] = isFirstFrame ? 0x90 : 0x80; // Mark S bit, indicates start of frame: payloadDescriptorBuf[0] |= 0b00010000;
34
+ payloadDescriptorBuf[1] = 0x80;
35
+ // Vp8 pictureid payload extension
36
+ const pictureIdBuf = Buffer.alloc(2);
37
+ pictureIdBuf.writeUintBE(this.count, 0, 2);
38
+ pictureIdBuf[0] |= 0x80;
39
+ return Buffer.concat([headerExtensionBuf, payloadDescriptorBuf, pictureIdBuf, buffer]);
40
+ }
41
+
42
+ codecCallback(chunk) {
43
+ const chunkSplit = this.partitionVideoData(chunk);
44
+ for (let i = 0; i < chunkSplit.length; i++) {
45
+ this._playChunk(this.makeChunk(chunkSplit[i], i == 0), i + 1 === chunkSplit.length);
46
+ }
47
+ }
48
+ }
49
+
50
+ module.exports = {
51
+ VP8Dispatcher,
52
+ };