-
-
Notifications
You must be signed in to change notification settings - Fork 102
/
Copy pathlanding.html
991 lines (919 loc) · 74.6 KB
/
landing.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Social Stream Ninja | Live Social Messaging for Content Creators</title>
<meta name="description" content="Social Stream Ninja consolidates live social messaging from YouTube, Twitch, Facebook, TikTok and more into a customizable dashboard. Enhance your live streaming with chat overlays, bot actions, and text-to-speech.">
<meta name="keywords" content="social stream, live chat, OBS overlay, chat relay, multi-platform chat, content creators, live streaming tools">
<meta name="author" content="Social Stream Ninja">
<link rel="icon" type="image/x-icon" href="./favicon.ico">
<link rel="stylesheet" href="styles.css">
<script async defer src="./thirdparty/buttons.js"></script>
<meta property="og:title" content="Social Stream Ninja | Enhance Your Live Streaming">
<meta property="og:description" content="Easily integrate chat messages from various platforms like YouTube, Twitch, and Facebook into your live streams with Social Stream Ninja.">
<meta property="og:url" content="https://socialstream.ninja">
<meta property="og:type" content="website">
<meta name="twitter:title" content="Social Stream Ninja | Live Chat Integration for Streamers">
<meta name="twitter:description" content="Social Stream Ninja, a free tool for streamers, integrates live chat from multiple platforms directly into OBS. Discover more at SocialStream.Ninja">
<link rel="canonical" href="https://socialstream.ninja/landing" />
<style>
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600&display=swap');
body, html {
margin: 0;
padding: 0;
font-family: 'Poppins', sans-serif;
color: #333;
background-color: #e5e5e5;
padding-bottom: 40px;
line-height: 1.6;
overflow-x: hidden;
}
header {
background: #1a1a1a; /* Darker shade for a rich appearance */
color: #fff;
padding: 20px;
text-align: center;
}
h1 {
margin: 0;
font-size: 2.4em;
}
#markdown h1 {
display:none;
}
p {
margin: 10px 0 0;
font-size: 1.2em;
}
#downloads {
text-align: center;
padding: 20px;
}
.download-btn {
background-color: #007bff; /* Brighter shade of blue */
color: white;
border: none;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 4px 2px;
cursor: pointer;
border-radius: 5px;
transition: background-color 0.3s;
}
.download-btn:hover {
background-color: #0056b3; /* Darker blue on hover */
color: white;
}
#video {
width: 100%;
text-align: center;
padding: 20px;
max-width: calc(100% - 40px);
}
iframe {
max-width: 100%;
border: none; /* Remove border for cleaner look */
}
.section {
padding: 20px 20px 40px 20px;
background-color: #fff;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
margin: 20px;
border-radius: 10px;
}
.faq-item h3 {
margin: 10px 0;
color: #333;
}
.faq-item p {
font-size: 1em;
color: #666;
}
footer {
background-color: #1a1a1a;
color: white;
text-align: center;
padding: 10px;
position: fixed;
bottom: 0;
width: 100vw;
}
footer p {
margin: 0;
}
a {
color: #007bff; /* Links color to match buttons */
text-decoration: none;
}
a:hover {
color: #0056b3; /* Darker blue on hover */
text-decoration: underline; /* Underline on hover for better visibility */
}
.github-btn {
background-color: #cecece;
color: black;
border: none;
padding: 12px 20px;
font-size: 16px;
border-radius: 5px;
text-decoration: none;
display: inline-block;
transition: background-color 0.3s;
margin-top: 12px;
}
.github-btn:hover {
background-color: #b0aeae;
}
#github-buttons {
text-align: center;
margin: 20px 0 10px 0;
}
.logo{
max-height: 1.2em;
}
#content {
background-color: #f8f8f8;
padding: 20px;
border-radius: 8px;
border: 1px solid #ddd;
}
#content h1, #content h2, #content h3 {
color: #333;
}
#content pre, #content code {
background-color: #eee;
border-radius: 5px;
padding: 5px;
font-family: 'Courier New', Courier, monospace;
}
#content a {
color: #007BFF;
text-decoration: none;
}
img {
max-width: 100%;
}
#notice {
background-color: #fffbe6;
border: 1px solid #ffe58f;
border-radius: 4px;
padding: 16px;
margin: 20px;
font-size: 14px;
line-height: 1.5;
}
#notice-header {
display: flex;
align-items: center;
margin-bottom: 10px;
}
#notice-header::before {
content: "\26A0"; /* Unicode for warning sign */
font-size: 24px;
margin-right: 10px;
color: #faad14;
}
#notice strong {
color: #d46b08;
}
#notice a {
color: #1890ff;
text-decoration: none;
}
#notice a:hover {
text-decoration: underline;
}
#notice ol {
margin-top: 10px;
margin-bottom: 10px;
padding-left: 20px;
}
#beta-downloads {
text-align: center;
margin: -10px 20px 20px 20px;
}
.beta-notice {
font-size: 0.9em;
color: #666;
margin: 0;
}
.beta-link {
color: #007bff;
font-weight: 500;
}
.beta-link:hover {
color: #0056b3;
}
</style>
</style>
</head>
<body>
<header>
<h1 style="margin-left: 22px;">Social Stream Ninja <img class="logo" src="https://socialstream.ninja/icons/icon-128.png"></h1>
<p>Consolidate your live social messaging streams and more</p>
<div id="github-buttons">
<a class="github-button" href="https://github.com/steveseguin/social_stream" data-size="large">
<svg viewBox="0 0 16 16" width="16" height="16" class="octicon octicon-mark-github" aria-hidden="true"><path d="M8 0c4.42 0 8 3.58 8 8a8.013 8.013 0 0 1-5.45 7.59c-.4.08-.55-.17-.55-.38 0-.27.01-1.13.01-2.2 0-.75-.25-1.23-.54-1.48 1.78-.2 3.65-.88 3.65-3.95 0-.88-.31-1.59-.82-2.15.08-.2.36-1.02-.08-2.12 0 0-.67-.22-2.2.82-.64-.18-1.32-.27-2-.27-.68 0-1.36.09-2 .27-1.53-1.03-2.2-.82-2.2-.82-.44 1.1-.16 1.92-.08 2.12-.51.56-.82 1.28-.82 2.15 0 3.06 1.86 3.75 3.64 3.95-.23.2-.44.55-.51 1.07-.46.21-1.61.55-2.33-.66-.15-.24-.6-.83-1.23-.82-.67.01-.27.38.01.53.34.19.73.9.82 1.13.16.45.68 1.31 2.69.94 0 .67.01 1.3.01 1.49 0 .21-.15.45-.55.38A7.995 7.995 0 0 1 0 8c0-4.42 3.58-8 8-8Z"></path></svg>
<span class="d-none d-sm-inline"> View on GitHub </span>
</a>
<a class="github-button" href="https://github.com/steveseguin/social_stream" data-icon="octicon-star" data-size="large" data-show-count="true" aria-label="Star yourusername/socialstream on GitHub">Star</a>
<a class="github-button" href="https://github.com/steveseguin/social_stream/fork" data-icon="octicon-repo-forked" data-size="large" data-show-count="true" aria-label="Fork yourusername/socialstream on GitHub">Fork</a>
<a class="github-button" href="https://github.com/steveseguin/social_stream/subscription" data-icon="octicon-eye" data-size="large" data-show-count="true" aria-label="Watch yourusername/socialstream on GitHub">Watch</a>
<a class="github-button" href="https://github.com/sponsors/steveseguin" data-icon="octicon-heart" data-size="large" aria-label="Sponsor @steveseguin on GitHub">Sponsor</a>
</div>
</header>
<section id="downloads">
<h2>Get Social Stream Ninja</h2>
<a href="https://github.com/steveseguin/social_stream/archive/refs/heads/main.zip" title="Manifest V2 version" onclick="setTimeout(function(){smoothScroll('to-install');},100);" class="download-btn">Chrome Extension</a>
<a href="https://github.com/steveseguin/social_stream/releases" class="download-btn" title="standalone app version">Windows App</a>
<a href="https://github.com/steveseguin/social_stream/releases" class="download-btn" title="standalone app version">macOS App</a>
<a href="https://github.com/steveseguin/social_stream/releases" class="download-btn" title="standalone app version">Linux App</a>
<a href="https://chromewebstore.google.com/detail/social-stream-ninja/cppibjhfemifednoimlblfcmjgfhfjeg" title="Manifest Version 3 version of Social Stream Ninja; available via the Chrome Webstore" class="download-btn">Chrome Webstore (v3)</a>
</section>
<section id="beta-downloads">
<p class="beta-notice">Looking for beta versions? <a href="https://beta.socialstream.ninja" class="beta-link">Visit our beta downloads page</a></p>
</section>
<section id="notice" style="display:none;">
<div id="notice-header">
<strong>Update August 22nd::</strong>
</div>
<p> If you're experiencing new issues with messages not working, please follow these steps:</p>
<ol>
<li>Refresh your browser sources in OBS to clear the browser cache. (there's a button at the bottom of the browser source settings)</li>
<li>Try toggling the extension off and on again.</li>
<li>If problems persist, enable the "via server" options in the extension's global settings menu, and then open new links.</li>
</ol>
<p>Still having trouble? Join our Discord for support: <a href="https://discord.socialstream.ninja">https://discord.socialstream.ninja</a> 🆘</p>
</section>
<section id="video">
<h2>Demo Video</h2>
<iframe width="560" height="315" src="https://www.youtube.com/embed/hZVTXqjFm9M" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</section>
<section id="markdown" class="section">
<h1 id="social-stream">Social Stream Ninja</h1>
<p>Consolidates your live social messaging streams and more</p>
<p> <a href="#to-install">Jump to Download and Install instructions</a></p>
<ul>
<li>Supports live automated two-way chat messaging with Facebook, Youtube, Twitch, Zoom, and dozens more</li>
<li>Includes a "featured chat" overlay, with messages selectable via the dockable dashboard; auto or manual selection.</li>
<li>Supports bot-commands and automated chat responses, with custom logic supported via scriptable plugin file.</li>
<li>Text-to-speech support, along with many other niche features supported.</li>
<li>Multi-channel source-icon support, so you can differentiate between different streams and creators</li>
<li>No user login, API key, or permission needed to capture the chat messages from most sites and services.</li>
<li>Queuing of messages for later highlighting</li>
<li>Free community support at <a href="https://discord.socialstream.ninja">https://discord.socialstream.ninja</a></li>
</ul>
<p>Social Stream Ninja (SSN) makes use of VDO.Ninja's data-transport API to stream data securely between browser windows with extremely low latency and all for free!</p>
<p><img src="https://user-images.githubusercontent.com/2575698/148505639-972eec38-7d8b-4bf3-9f15-2bd02182591e.png" alt="image"> <img src="https://user-images.githubusercontent.com/2575698/148505691-8a08e7b0-29e6-4eb5-9632-9dbcac50c204.png" alt="image"></p>
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
<h3 id="official">Visit the official support site</h3>
<p>Over a hundred sites are supported, including Youtube, Twitch, Tiktok, Facebook, Instagram, X, Kick, and Zoom.</p>
<p>Please see <a href="https://socialstream.ninja">the official documentation</a> for a list of all the supported sites and more information on using Social Stream Ninja.</p>
<p><strong>Table of Contents</strong></p>
<ul>
<li><a href="#supported-sites">Supported sites:</a><ul>
<li><a href="#chat-graveyard-">Chat graveyard 🪦🪦🪦</a></li>
</ul>
</li>
<li><a href="#video-walk-thru">Video walk-thru</a></li>
<li><a href="#to-install">To install</a><ul>
<li><a href="#seeing-an-error-message">Seeing an error message?</a></li>
<li><a href="#updating">Updating</a></li>
<li><a href="#firefox-support">Firefox support</a></li>
</ul>
</li>
<li><a href="#standalone-version-of-the-app">Standalone version of the app</a></li>
<li><a href="#to-use-the-extension">To use the extension</a></li>
<li><a href="#customize">Customize</a><ul>
<li><a href="#more-advanced-styling-customizations">More advanced styling customizations</a></li>
<li><a href="#removing-text-outlines">Removing text-outlines</a></li>
<li><a href="#changing-the-background-alternative-line-colors-in-the-dock">Changing the background alternative line colors in the dock</a></li>
</ul>
</li>
<li><a href="#changing-css-without-obs">Changing CSS without OBS</a></li>
<li><a href="#pre-styled-templates--themes">Pre-styled templates / themes</a><ul>
<li><a href="#custom-overlays-from-scratch">Custom Overlays from scratch</a></li>
<li><a href="#custom-javascript">Custom Javascript</a></li>
<li><a href="#auto-responding--custom-actions">Auto responding / custom actions</a></li>
</ul>
</li>
<li><a href="#queuing-messages">Queuing messages</a></li>
<li><a href="#pinning-messages">Pinning messages</a></li>
<li><a href="#togglable-menu-commands">Togglable Menu Commands</a></li>
<li><a href="#view-chat-while-gaming-always-on-top">View chat while gaming; always-on-top</a></li>
<li><a href="#hotkey-midi--streamlabs-support">Hotkey (MIDI / Streamlabs) support</a></li>
<li><a href="#server-api-support">Server API support</a><ul>
<li><a href="#social-streams-server-api-ingest-and-clear-messages-via-remote-request">Social Stream Ninja's server API (ingest and clear messages via remote request)</a></li>
<li><a href="#remote-server-api-support-publish-messages-to-third-parties">Remote server API support (publish messages to third parties)</a></li>
<li><a href="#inbound-third-party-donation-support">Inbound third-party donation support</a></li>
</ul>
</li>
<li><a href="#text-to-speech">Text to speech</a><ul>
<li><a href="#installing-different-language-speech-packs">Installing different language-speech packs</a></li>
<li><a href="#premium-tts-voice-options">Premium TTS voice options</a></li>
</ul>
</li>
<li><a href="#branded-channel-support">Branded channel support</a></li>
<li><a href="#random-other-commands-not-documented-elsewhere">Random other commands not documented elsewhere</a></li>
<li><a href="#known-issues-or-solutions">Known issues or solutions</a><ul>
<li><a href="#chat-stops-when-put-in-the-background-or-minimized">Chat stops when put in the background or minimized</a></li>
<li><a href="#blue-bar-appears-or-chat-responder-not-working">Blue bar appears or chat responder not working</a></li>
<li><a href="#cant-export-settings-or-save-files">Can't export settings or save files</a></li>
<li><a href="#other-issues">Other issues</a></li>
</ul>
</li>
<li><a href="#requesting-a-site">Requesting a site</a></li>
<li><a href="#adding-sites-yourself">Adding sites yourself</a></li>
<li><a href="#support">Support</a></li>
<li><a href="#donations">Donations</a></li>
<li><a href="#icons">Icons</a></li>
<li><a href="#credit">Credit</a></li>
<li><a href="#contributors-to-this-project">Contributors to this project</a></li>
</ul>
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<h3 id="supported-sites">Supported sites [archived support list]:</h3>
<ul>
<li>twitch.tv - pop out chat to trigger</li>
<li>youtube live - pop out the chat to trigger (studio or guest view); or add &socialstream to the YT link</li>
<li>youtube static comments - click SS in the top right corner of Youtube, then select the message you wish to publish inside the YT comment section via the new buttons there.</li>
<li>facebook live - guest view, publisher view, or the producer's pop-up chat on the web is supported.</li>
<li>workplace.com - (same setup as Facebook)</li>
<li>zoom.us (web version)</li>
<li>owncast demo page (<code>watch.owncast.online</code>, or for a pop-out chat version, open <code>https://watch.owncast.online/embed/chat/readwrite/</code> )</li>
<li>crowdcast.io</li>
<li>livestream.com</li>
<li>mixcloud.com (pop out chat)</li>
<li>ms teams (teams.live.com and teams.microsoft.com)</li>
<li>vimeo.com (either the vimeo.com/events/xxx pages or <a href="https://vimeo.com/live-chat/xxxxxxxxx/interaction/">https://vimeo.com/live-chat/xxxxxxxxx/interaction/</a>)</li>
<li>instagram live (instagram.com/*/live/), css note: <code>[data.type = "instagramlive"]</code></li>
<li>Instagram post non-live comments (REQUIRES the TOGGLE in menu to enable it), css note: <code>[data.type = "instagram"]</code></li>
<li>instafeed.me (no pop out; alternative instagram live support)</li>
<li>tiktok live (tiktok.com/*/live)</li>
<li>webex live chat (not the pop out)</li>
<li>linkedin events and live comments. (works with linkedin.com/videos/live/* or linkedin.com/videos/events/* or linkedin.com/events/*)</li>
<li>vdo.ninja (pop-out chat)</li>
<li>Whatsapp.com (REQUIRES the TOGGLE in menu to enable it; use @ <a href="https://web.whatsapp.com">https://web.whatsapp.com</a> ; fyi, no avatar support)</li>
<li>discord.com (web version; requires toggle enabled via the settings as well) </li>
<li>telegram (web.telegram.org in stream mode; requires toggle enabled)</li>
<li>slack (<a href="https://app.slack.com/">https://app.slack.com/</a> ; required toggle enabled to use)</li>
<li>Google Meet ; required toggle enabled to use. (You can specify your own name, rather than "You", via the host/bot section in the extension menu)</li>
<li><img src="https://user-images.githubusercontent.com/2575698/178857380-24b3a0fc-bf86-4645-91ec-24893df19279.png" alt="Requires toggling to enable certain integrations"> telegram, slack, whatsapp, discord require an extra step to enable. See this video for more help: <a href="https://www.youtube.com/watch?v=L3l0_8V1t0Q">https://www.youtube.com/watch?v=L3l0_8V1t0Q</a></li>
<li>restream.io chat supported (<a href="https://chat.restream.io/chat">https://chat.restream.io/chat</a>)</li>
<li>amazon.com/live</li>
<li>wix.com (<a href="https://manage.wix.com/dashboard/*/live-video/">https://manage.wix.com/dashboard/*/live-video/</a>*)</li>
<li>clouthub (no pop out; just the video page)</li>
<li>rumble.com (pop out chat)</li>
<li>trovo.live (open the chat pop-up page; ie: <a href="https://trovo.live/chat/CHANNEL_NAME_HERE">https://trovo.live/chat/CHANNEL_NAME_HERE</a>)</li>
<li>Dlive.tv (pop-out chat)</li>
<li>Picarto.tv (pop-out chat; ie: <a href="https://picarto.tv/chatpopout/CHANNELNAMEHERE/public">https://picarto.tv/chatpopout/CHANNELNAMEHERE/public</a>)</li>
<li>Mobcrush (this page: <a href="https://studio.mobcrush.com/chatpopup.html">https://studio.mobcrush.com/chatpopup.html</a>)</li>
<li>vimm.tv (<a href="https://www.vimm.tv/c/xxxxxxxx">https://www.vimm.tv/c/xxxxxxxx</a>)</li>
<li>odysee.com (via the pop out chat I think)</li>
<li>minnit.chat support (<a href="https://minnit.chat/xxxxxxxxxxx?mobile&popout">https://minnit.chat/xxxxxxxxxxx?mobile&popout</a>)</li>
<li>livepush.io (chat overlay link provided; no input field support?)</li>
<li>piczel.tv (pop out chat @ <a href="https://piczel.tv/chat/xxxxxxxxx">https://piczel.tv/chat/xxxxxxxxx</a>)</li>
<li>bilibili.tv added (just regular view page /w chat; no pop out)</li>
<li>Amazon Chime (<a href="https://app.chime.aws/meetings/xxxxxxxxx">https://app.chime.aws/meetings/xxxxxxxxx</a>)</li>
<li>Locals.com (no pop out needed)</li>
<li>Nimo.TV (pop out chat, ie: <a href="https://www.nimo.tv/popout/chat/xxxx">https://www.nimo.tv/popout/chat/xxxx</a>)</li>
<li>kick.com (pop out chat)</li>
<li>quickchannel.com (<a href="https://play.quickchannel.com/">https://play.quickchannel.com/</a>*)</li>
<li>rokfin.com (<a href="https://www.rokfin.com/popout/chat/xxxxxx?stream=yyyyyy">https://www.rokfin.com/popout/chat/xxxxxx?stream=yyyyyy</a>)</li>
<li>sli.do (<a href="https://app.sli.do/event/XXXXXXXXXXXXXX/live/questions">https://app.sli.do/event/XXXXXXXXXXXXXX/live/questions</a>)</li>
<li>cbox.ws (no pop out needed)</li>
<li>castr.io (<a href="https://chat.castr.io/room/XXXXXXXX">https://chat.castr.io/room/XXXXXXXX</a>)</li>
<li>tellonym.me</li>
<li>peertube (triggers on: https://*/plugins/livechat/<em>router/webchat/room/</em>)</li>
<li>IRC (via <a href="https://webchat.quakenet.org/">https://webchat.quakenet.org/</a>)</li>
<li>Tradingview.com (just the normal viewer page; no pop out)</li>
<li>rooter.gg (no pop out; just pause the video I guess)</li>
<li>loco.gg (no pop out; just pause the video I guess)</li>
<li>buzzit.ca (community member submitted integration)</li>
<li>afreecatv.com (pop out the chat; you can't close the main window it seems tho?)</li>
<li>nonolive.com (no pop out; partial support added so far only)</li>
<li>stageTEN.tv</li>
<li>live.vkplay.ru (was vkplay.live) - pop out the chat</li>
<li>arena.tv (no pop out chat support, so just pause the video I guess)</li>
<li>bandlab.com (no pop out, so just pause the video I guess while chat open)</li>
<li>threads.net (a little funky star icon, right of the share icon, will select thread to push to dock)</li>
<li>floatplane.com (pop out chat; gotta keep the main window still open though? annoying..)</li>
<li>OpenAI chatGPT chat - (via <a href="https://chat.openai.com/chat">https://chat.openai.com/chat</a>). You must opt-in via the toggle for this though</li>
<li>live.space (Just open the basic watch page, or if their the pop out chat works for you, <a href="https://live.space/popout-chat/XXXXX">https://live.space/popout-chat/XXXXX</a>)</li>
<li>vstream.com (pop out chat)</li>
<li>estrim - live video chat supported</li>
<li>livestorm.io (open the 'external sidebar', which might be a plugin, and it should capture that)</li>
<li>boltplus.tv (pop out chat)</li>
<li>cozy.tv (no pop out; just open the view page)</li>
<li>steamcommunity.com (<a href="https://steamcommunity.com/broadcast/chatonly/XXXXXXXX">https://steamcommunity.com/broadcast/chatonly/XXXXXXXX</a>)</li>
<li>whatnot.com (no pop out, so just open the view page)</li>
<li>sessions.us - the meeting video chat; not popped out.(You can specify your own name, rather than "You", via the host/bot section in the extension menu)</li>
<li>jaco.live (<a href="https://jaco.live/golive">https://jaco.live/golive</a>)</li>
<li>Twitter Live video chat (X.com) (open the live broadcast; ie: <a href="https://twitter.com/i/broadcasts/XXXXXXXXXX">https://twitter.com/i/broadcasts/XXXXXXXXXX</a>) </li>
<li>Twitter static feed posts -- you will need to click "Enable Overlay" in the lower right of X to have X posts be supported. Manually click then to select which post.</li>
<li>younow.com - ( just open the video as normal with chat on the side; there's no pop out chat, so the link is just <a href="https://www.younow.com/USERNAME">https://www.younow.com/USERNAME</a> )</li>
<li>shareplay.tv (pop out chat, ie: <a href="https://www.shareplay.tv/chat/usernamehere/9fd3a9ee-a915-4f8b-b23d-xxxxxxxxxxx">https://www.shareplay.tv/chat/usernamehere/9fd3a9ee-a915-4f8b-b23d-xxxxxxxxxxx</a>)</li>
<li>truffle.vip (<a href="https://chat.truffle.vip/chat/">https://chat.truffle.vip/chat/</a>*)</li>
<li>megaphonetv.com (In <a href="https://studio.megaphonetv.com/">Studio</a>, select UGC, then open Recent messages)</li>
<li>pilled (pop out the chat)</li>
<li>riverside.fm (just open the chat bar. Note: you can opt-out of capture via the extension menu)</li>
<li>chzzk.naver.com (pop out the chat)</li>
<li>demo.openstreamingplatform.com (pop out chat)</li>
</ul>
<p><a href="#requesting-a-site">More on request</a></p>
<h3 id="video-walk-thru">Video walk-thru</h3>
<p>Install guide for the extension: <a href="https://www.youtube.com/watch?v=Zql6Q5H2Eqw">https://www.youtube.com/watch?v=Zql6Q5H2Eqw</a></p>
<p>A bit about Social Stream Ninja (old now): <a href="https://www.youtube.com/watch?v=X_11Np2JHNU">https://www.youtube.com/watch?v=X_11Np2JHNU</a></p>
<p>How to setup for discord, slack, whatsapp, meet, and telegram, see: <a href="https://www.youtube.com/watch?v=L3l0_8V1t0Q">https://www.youtube.com/watch?v=L3l0_8V1t0Q</a></p>
<h3 id="to-install">To install</h3>
<p>This extension should work with Chromium-based browser on systems that support webRTC. This includes Chrome, Edge, and Brave. <a href="https://github.com/steveseguin/social_stream#firefox-support">Firefox users see here</a>.</p>
<p>Currently you must download, extract, and load the browser extension manually. It is not available yet in the browser's web store.</p>
<p>The link to download newest version is here: <a href="https://github.com/steveseguin/social_stream/archive/refs/heads/main.zip">https://github.com/steveseguin/social_stream/archive/refs/heads/main.zip</a></p>
<p>Once extracted into a folder, you can go here to load it: chrome://extensions/</p>
<p><img src="https://user-images.githubusercontent.com/2575698/142858940-62d88048-5254-4f27-be71-4d99ea5947ab.png" alt="image"></p>
<p>Ensure you have Developer Mode enabled; then you can just load the extension via the load unpacked button and selecting the folder you extracted the fiels to.</p>
<p><img src="https://user-images.githubusercontent.com/2575698/142857907-80428c61-c192-4bff-a1dc-b1a674f9cc4a.png" alt="image"></p>
<p>You're ready to start using it! </p>
<p>Please note also that you will need to manually update the extension to access newer versions; it currently does not auto-update aspects of the extension; just the dock and single overlay page auto-update as they are hosted online.</p>
<h4 id="seeing-an-error-message">Seeing an error message?</h4>
<p>If you see the browser say there is an "Error", specifically a manifest v2 warning or something, you can safely ignore it. It is not actually an error and will not impact the function of the extension.</p>
<p>Something of concern though is Google will be updating Chrome browsers on January 2023 to block many popular Chrome extensions, including many Adblockers and also Social Stream Ninja. I'm working to resolve this concern, but Social Stream Ninja may end up having diminished functionality if Google has their way. If necessary, Social Stream may evolve into a downloadable app instead to avoid these limiations, but I'm hoping to avoid that if possible.</p>
<h4 id="updating">Updating</h4>
<p>To update, just download the extension, replace the old files with the new files, and then reload the extension or completely restart the browser. If just reloading the extension, you may then need to also reload any open chat sites that you wish to use Social Stream Ninja with.</p>
<p>You can download the newest version here: <a href="https://github.com/steveseguin/social_stream/archive/refs/heads/main.zip">https://github.com/steveseguin/social_stream/archive/refs/heads/main.zip</a></p>
<p>Please note: DO NOT Uninstall the extension if you want to update it. This will delete all your settings. Replace the files, and reload the extension or browser instead. If you MUST uninstall, you can export your settings to disk and reload them after you have reinstalled. </p>
<p>New app integrations do not auto-update; just the overlay and dock page will auto-update. It's suggeseted you update every now and then manually, or whenever you encounter a bug. I'll try to resolve this issue down the road, perhaps with a standalone desktop app eventually.</p>
<p>And for a video that covers two ways to update the extension: <a href="https://youtu.be/Zql6Q5H2Eqw?t=612">https://youtu.be/Zql6Q5H2Eqw?t=612</a></p>
<p>(If using the Standalone app version of SocialStream, and not the extension, it will auto update when you reload/reopen)</p>
<h4 id="firefox-support">Firefox support</h4>
<p>I no longer offer official Firefox support, but you can still try to get it going with the steps below:</p>
<ul>
<li><p>Download+extract or clone the SocialStream code somewhere.</p>
</li>
<li><p>Go to <code>about:debugging#/runtime/this-firefox</code> in Firefox and select Load Temporary Add-on. </p>
</li>
<li><p>Select any file inside the SocialStream folder.</p>
</li>
<li><p>You're done. This is a temporary install and none of the settings made will be persist, including your session ID.</p>
</li>
</ul>
<p>You will still need to manually redo these steps to update when needed, but you can use the newest version of the code.</p>
<h3 id="standalone-version-of-the-app">Standalone version of the app</h3>
<p>There is an upcoming standalone version of Social Stream Ninja, which installs as an app, rather than as a browser extension.</p>
<p>To try out the preview test version of the app, you can download it below, but keep in mind that the bugs are still being worked out:</p>
<p><a href="https://github.com/steveseguin/social_stream/releases">https://github.com/steveseguin/social_stream/releases/</a>
Mac and PC are supported currently, with Linux support coming later on.</p>
<p>Please note: If using the same session ID in both the browser extension and the standalone version, you will only be able to use one at a time. </p>
<h3 id="to-use-the-extension">To use the extension</h3>
<p>Open Twitch or Youtube "Pop out" chat; or just go to your Facebook Live chat while connected to Ethernet or WiFi. You must not minimize or close these windows, but they can be left in the background or moved to the side.</p>
<p>Then, press the Social Stream Ninja chrome extension button and ENABLE streaming of chat data. (Red implies disabled. Green is enabled)</p>
<p><img src="https://user-images.githubusercontent.com/2575698/142856707-0a6bc4bd-51b4-4cd0-9fa3-ef5a1adfcbf7.png" alt="image"></p>
<h5 id="please-note--if-the-extensions-icon-is-red-then-it-means-it-is-still-off-and-wil-not-work--you-have-to-click-enable-extension-and-the-icon-must-change-to-the-color-green">Please note: If the Extension's icon is RED, then it means it is still off and wil not work. You have to click "Enable extension", and the icon must change to the color green.</h5>
<p>Next, using the provided two links, you can manage the Social Stream Ninja of chat messages and view selected chat messages as overlays.</p>
<p><img src="https://user-images.githubusercontent.com/2575698/142935393-4ca90418-a645-45e3-8e37-f4884e16457a.png" alt="image"></p>
<p>You can hold ALT on the keyboard to resize elements in OBS, allowing you to crop the chat stream if you want to hide aspects like the time or source icon.</p>
<p>Clicking on a message will have it appear in the overlay link. You can press the clear button to hide it or use the &showtime=20000 URL option added to the overlay page to auto-hide it after 20-seconds (20,000 ms).</p>
<p><img src="https://user-images.githubusercontent.com/2575698/142854951-fe1f34c9-0e24-495f-8bfe-a33ab69fa7cb.png" alt="image"></p>
<p>There is a &darkmode option, but the default is white, for the dock.</p>
<p><img src="https://user-images.githubusercontent.com/2575698/142855585-45c11625-c01c-4cc0-bfe0-cde4aed5fc44.png" alt="image"></p>
<p>A good resolution for the overlay is either 1280x600 or 1920x600; you can specify this in the OBS browser source. You can edit the style of the overlay using the OBS CSS style input text box. The chat overlay will appear 50-px from the bottom currently, but the height of the chat window can be quite tall; to avoid the name of the overlay being cropped, just make sure you give it enough room.</p>
<p><img src="https://user-images.githubusercontent.com/2575698/142855680-74f6055d-7b79-4e9a-ae7d-909c7f677a24.png" alt="image"></p>
<p>If using the automated chat response options, like auto-hi, you must ensure the Youtube/Twitch/Facebook chat input options are enabled and that you are able to send a chat message. Manually entering a chat message into the pop-out window or into the Facebook live chat area first can help ensure things are working are intended, else automated message may not be sent.</p>
<h5 id="note-if-things-do-not-work">Note: If things do not work,</h5>
<ul>
<li>Toggle the extension on and off, and reload the pop-out chat window. Ideally the pop-out chat should be visible on screen, as even just a few pixels shown will allow the pop-out chat to work at full-power. Chrome otherwise may throttle performance.</li>
<li>Open a new dock / overlay link if things still do not work, as the session ID may have changed.</li>
<li>Ensure that VDO.Ninja works with your browser, as if not, webRTC may be disabled and so this Social Stream Ninja extension will not work also.</li>
<li>If using Facebook live chat, please sure you are viewing the page as a "viewer", not as a publisher, and that you are connected to WiFi or Ethernet, and not mobile LTE/4G/5G.</li>
<li>The auto-responder requires you to be signed in to the social endpoint and that you have access to chat; ensure you accept any disclaimer and try issuing a test message first.</li>
<li>Try using the extension in Incognito mode or try disabling all other browser extensions, then reloading the browser, and trying again. Many extension types will conflict with Socialstream, causing certain functions to fail.</li>
</ul>
<h3 id="customize">Customize</h3>
<p>There are quite a few toggles available to customize functions and styles, but these toggles often just apply URL parameters. You can as a result, just manually apply the parameters yourself, opening up more fine-grain control. A list of some of the options are available below.</p>
<p>To customize the dock, you can use the following options:</p>
<ul>
<li>&lightmode (Enables the dark-mode for the chat stream)</li>
<li>&scale=2 (doubles size/resolution of all elements)</li>
<li>&notime (hides the date in the chat stream)</li>
<li>&hidesource (hides the youtube/twitch/fb icons from the stream)</li>
<li>&compact (Removes the spacing between name and message)</li>
<li>&autoshow (will auto-feature chat messages as they come into the dock at a rate of about 2 per 3 seconds)</li>
<li>&attachmentsonly (will only show image attachments in the dock; the messages will be wiped)</li>
</ul>
<p>To customize the featured chat overlay, the following URL parameters are available</p>
<ul>
<li>&showtime=20000 (auto-hides selected messages after 20s)</li>
<li>&showsource (shows the youtube/twitch/fb icons next to the name)</li>
<li>&fade (will have featured messages fade in, rather than pop up)</li>
<li>&swipe (will have featured messages swipe in from the left side)</li>
<li>&center (center featured messages)</li>
</ul>
<p>To customize the color, font-size and styling, you can edit the CSS, in either the OBS browser source style-sheet section, or by editing the and using the index.html file. See below:</p>
<h4 id="more-advanced-styling-customizations">More advanced styling customizations</h4>
<p>To further customize the appearance of the overlay or dock, you can make CSS style changes via OBS browser source, without any coding. </p>
<p><img src="https://user-images.githubusercontent.com/2575698/153123085-4cf2923e-fce3-40bd-bd66-3ba14a6ab321.png" alt="image"></p>
<pre><code>body { background-color: rgba(0, 0, 0, 0); margin: 0px auto; overflow: hidden; }
:root {
--comment-color: #090;
--comment-bg-color: #DDD;
--comment-color: #FF0;
--comment-border-radius: 10px;
--comment-font-size: 30px;
--author-border-radius: 10px;
--author-bg-color: #FF0000;
--author-avatar-border-color: #FF0000;
--author-font-size: 32px;
--author-color: blue;
--font-family: "opendyslexic", opendyslexic, serif;
}
@font-face {
font-family: 'opendyslexic';
src: url('https://vdo.ninja/examples/OpenDyslexic-Regular.otf');
font-style: normal;
font-weight: normal;
}
.hl-name{
padding: 2px 10px !important;
}
</code></pre>
<p>Sample CSS of which you can use to customize some of the basic styles. There's not much that you can't do via CSS in this way, but you can edit things further at a code-level if needed. Mac/Linux users may face issues with OBS not liking self-hosted versions of the index/dock file, but it's not an issue for the PC version.</p>
<p>It's important in some cases to add <code>!important</code> at the end of some CSS values, to force them into use.</p>
<h4 id="removing-text-outlines">Removing text-outlines</h4>
<p>Try:</p>
<pre><code>body {
text-shadow: 0 0 black;
}
</code></pre>
<h4 id="changing-the-background-alternative-line-colors-in-the-dock">Changing the background alternative line colors in the dock</h4>
<p>In OBS browser source, for the CSS style, add the following to customize the alternative colors</p>
<pre><code>:root {
--highlight-base: #333!important;
--highlight-base2: #888!important;
--highlight-compact: #333!important;
--highlight-compact2: #888!important;
}
</code></pre>
<p>Note that <code>--highlight-compact</code> and <code>--highlight-compact2</code> are needed if using &compact mode, while the other two are the default background alternative colors. Using <code>!important</code> is needed to force override the style.</p>
<h3 id="changing-css-without-obs">Changing CSS without OBS</h3>
<p>You can also pass custom CSS to the dock and index page via URL parameters using either &css or &b64css.</p>
<p><code>&css=https://youdomain.com/style.css</code> or <code>&b64css=YOUR_CSS_CODE_HERE</code></p>
<p>You can use this tool to encode the URL you want to link to: <a href="https://www.urlencoder.org/">https://www.urlencoder.org/</a></p>
<p>For the base64 css option, you can create the base64 encoding using <code>btoa(encodeURIComponent(csshere))</code> via the browser's developer console. For example:</p>
<p><code>window.btoa(encodeURIComponent("#mainmenu{background-color: pink; ❤" ));</code></p>
<p>The above will return the base64 encoded string required. Special non-latin characters are supported with this approach; not just latin characters.</p>
<p>Example of what it might look like:
<a href="https://socialstream.ninja/?64css=JTIzbWFpbm1lbnUlN0JiYWNrZ3JvdW5kLWNvbG9yJTNBJTIwcGluayUzQiUyMCVFMiU5RCVBNA">https://socialstream.ninja/?64css=JTIzbWFpbm1lbnUlN0JiYWNrZ3JvdW5kLWNvbG9yJTNBJTIwcGluayUzQiUyMCVFMiU5RCVBNA</a></p>
<h3 id="pre-styled-templates--themes">Pre-styled templates / themes</h3>
<p>You can try out some stylized chat overlays in the themes folder:</p>
<p>An example of one is available here: <a href="https://socialstream.ninja/themes/pretty.html?session=SESSIONIDHERE">https://socialstream.ninja/themes/pretty.html?session=SESSIONIDHERE</a></p>
<p><img src="https://user-images.githubusercontent.com/2575698/193437450-545f7f4c-d5fc-465b-9cfe-d42f82671c51.png" alt="image"></p>
<p>For anyone who wants to create a custom theme/style/template for their chat stream, you can share them via adding them to this repository as a Pull Request.</p>
<h4 id="custom-overlays-from-scratch">Custom Overlays from scratch</h4>
<p>For those so inclined to make their own overlays for Social Stream Ninja from scratch, I've created a basic and bare HTML template for reference.</p>
<p>Check it out here: <a href="https://socialstream.ninja/sampleoverlay?session=XXXXX">https://socialstream.ninja/sampleoverlay?session=XXXXX</a></p>
<ul>
<li>There are no functions like TTS or style customization via URL parameters; it's just a simple fixed overlay with minimal code</li>
<li>It can be used as a featured overlay or as a dock-alternative, with all messages. In the code, toggle <code>featuredMode</code> on or off, depending on whether you want it work with featured messages only, or all incoming messages.</li>
<li>You can edit and load it via your browser locally, without needing to host it. Keep it perhaps in a different folder than Social Stream Ninja though to avoid having it deleted after an update.</li>
</ul>
<p><img src="https://github.com/steveseguin/social_stream/assets/2575698/26f26421-ac44-47f7-bcfc-04627deb85f9" alt="image"></p>
<h4 id="custom-javascript">Custom Javascript</h4>
<p>You can inject a bit of javascript into the dock or index pages using <code>&js={URL ENCODED JAVASCRIPT}</code></p>
<p>For example,
<a href="https://socialstream.ninja/index.html?session=test123&js=https%3A%2F%2Fvdo.ninja%2Fexamples%2Ftestjs.js">https://socialstream.ninja/index.html?session=test123&js=https%3A%2F%2Fvdo.ninja%2Fexamples%2Ftestjs.js</a></p>
<h4 id="auto-responding--custom-actions">Auto responding / custom actions</h4>
<p>You can create your own custom auto-responding triggers or other actions by including a <code>custom.js</code> file. You don't need to host the index or dock file for this.</p>
<p>Included in the code is the <code>custom_sample.js</code> file, which you can rename to custom.js to get started. Included in it is the <code>&auto1</code> trigger, which auto responds "1" to any message that is also "1". You need to add <code>&auto1</code> to the dock's URL to activate it.</p>
<p>It's fairly easy to modify the <code>auto1</code> trigger to do whatever you want. You can also customize or remove the URL-parameter trigger needed to activate it.</p>
<p>Please note that currently the custom.js file needs the dock.html to be opened locally, if you wish to have it load there.</p>
<h3 id="queuing-messages">Queuing messages</h3>
<p>If you hold CTRL (or cmd on mac), you can select messages in the dock that get added to a queue. A button should appear in the top dock menu bar that will let you cycle through the queue, one at a time. When pressing the Next in Queue button, messages from the queue will appear as featured chat messages in the overlay page.</p>
<h3 id="pinning-messages">Pinning messages</h3>
<p>Like queuing a message, you can also instead hold down the ALT key while clicking a message to pin it; it will stay at the top of the page, until unpinned in the same fashion.</p>
<h3 id="togglable-menu-commands">Togglable Menu Commands</h3>
<p>These are some generic auto-reply commands that can be toggled on/off via the extension's menu. They do not need a custom.js file to work</p>
<ul>
<li>!joke (tells a random geeky dad joke)</li>
<li>hi (Welcomes anyone who says "hi" into chat)</li>
</ul>
<h3 id="view-chat-while-gaming-always-on-top">View chat while gaming; always-on-top</h3>
<p>The Standalone desktop version of Social Stream Ninja can pin windows on top of other applications, and can have the background be transparent. The Standalone app is still early in its development, so instead you might want to consider the Electron Capture app instead. It offers the ability to keep any browser window on top of your apps, such as while gaming, and there is a hotkey function to toggle user input when needing to interact with it.</p>
<p>check it out here: <a href="https://github.com/steveseguin/electroncapture">https://github.com/steveseguin/electroncapture</a></p>
<p><img src="https://github.com/steveseguin/social_stream/assets/2575698/9c9c9da7-5656-45f8-ab86-5be56099d970" alt="image"></p>
<h3 id="hotkey-midi--streamlabs-support">Hotkey (MIDI / Streamlabs) support</h3>
<p>There's a toggle to enable MIDI hotkey support. This allows a user to issue commands to the extension when active, such as issue predefined chat messages to all social destinations.</p>
<p>The hotkeys can be issued via MIDI, which can be applied to a Streamdeck also via a virtual MIDI device. The MIDI actions available currently include:</p>
<p>Using Control Change MIDI Commands, on channel 1:</p>
<ul>
<li>command 102, with value 1: Say "1" into all chats</li>
<li>command 102, with value 2: Say "LUL" into all chats</li>
<li>command 102, with value 3: Tell a random joke into all chats</li>
<li>command 102, with value 4: Clear all featured chat overlays</li>
</ul>
<p><img src="https://user-images.githubusercontent.com/2575698/144830051-20b11caa-ba63-4223-80e1-9315c479ebd6.png" alt="image"></p>
<p>The StreamDeck MIDI plugin can be found in the Streamdeck store pretty easily. </p>
<p>Please note that you will also need a MIDI Loopback device installed if using the StreamDeck MIDI plugin. For Windows, you can find a virtual MIDI loopback device here: <a href="https://www.tobias-erichsen.de/software/loopmidi.html">https://www.tobias-erichsen.de/software/loopmidi.html</a> There are some for macOS as well.</p>
<p><img src="https://user-images.githubusercontent.com/2575698/186810050-c6b026f2-3642-4bed-a3b2-f954b1d5b507.png" alt="image"></p>
<p>Lastly, please note that you will need to enable the MIDI option in the menu options for it to work, as it is not loaded by default.</p>
<p><img src="https://user-images.githubusercontent.com/2575698/186801053-6319d63e-fe92-42bc-b951-cad4d35753cc.png" alt="image"></p>
<h3 id="server-api-support">Server API support</h3>
<p>You can send messages to Social Stream Ninja via the hosted server ingest API, and you can also send messages from Social Stream Ninja to remote third-parties. Many options are supported; perhaps more than what is listed below.</p>
<p>A simple use case is to ingest a donation from a third party via webhook. You can push those dono notifications to Social Stream Ninja and show as an overlay. You can also use a third-party service to overlay messages captured by Social Stream Ninja. More below.</p>
<h4 id="social-streams-server-api-ingest-and-clear-messages-via-remote-request">Social Stream Ninja's server API (ingest and clear messages via remote request)</h4>
<p>If using the MIDI API isn't something you can use, you can also check out the hosted API service to send messages to SocialStream, which will be redirected to your social live chat sites. This API works with a Stream Deck or custom applications.</p>
<p>This API end point supports WSS, HTTPS GET, and HTTP POST (JSON). Support for this API must be toggled on in the menu settings; there's several different toggles you may want to enable, depending on which HTTP/WSS API you want to use</p>
<h5 id="a-couple-common-examples">A couple common examples</h5>
<p>An overly simple example of how to use the GET API would be: <a href="https://io.socialstream.ninja/XXXXXXXXXX/sendChat/null/Hello">https://io.socialstream.ninja/XXXXXXXXXX/sendChat/null/Hello</a>, which sends HELLO. Replace XXXXX with your Social Stream Ninja session ID. Other options, like <code>https://io.socialstream.ninja/XXXXXXXXXX/clearOverlay</code> should work, too.</p>
<p>You can use this API to clear the featured-chat, poke the next-in-queue item, and more. It works with WSS or HTTP requests.</p>
<h5 id="target-specific-docks">Target specific docks</h5>
<p>You can also target specific docks with your API requests by assigning a target name to each dock.html page using <code>&label</code>.</p>
<p>For example, to set a dock with the target name of "NAMEHERE", we'd do: <code>https://socialstream.ninja/dock.html?session=XXXXXXXXXXXXX&server&sync&label=NAMEHERE</code>. From there, we can target it with the API format like this: <code>https://io.socialstream.ninja/XXXXXXXXXXXXX/nextInQueue/NAMEHERE/null</code>. This all may be needed because if you have multiple docks connected to the API interface, you may not want to trigger the same command multiple times in all cases.</p>
<h5 id="more-details">More details</h5>
<p>For details of the commands, see the following link for sample functionality and refer to its source code for examples.</p>
<p><a href="https://socialstream.ninja/sampleapi.html?session=xxxxxxxxxx">https://socialstream.ninja/sampleapi.html?session=xxxxxxxxxx</a> (replacing xxxxxxxx with your Social Stream Ninja session ID to have it work)</p>
<p>More functionality can be added on request.</p>
<p><img src="https://user-images.githubusercontent.com/2575698/189367779-67969f47-a305-4347-9a37-053b33479602.png" alt="image"></p>
<h4 id="remote-server-api-support-publish-messages-to-third-parties">Remote server API support (publish messages to third parties)</h4>
<p>Remote API support is available via dock page or extensions. You can currently auto-publish messages via the dock with the &autoshow parameter, but there's also an option to publish to the featured chat via the dock directly. To capture these messages, you can use the websocket API server, which requires enabling a toggle in the General mechanics section. You can also publish messages via POST/PUT to an HTTP webserver, rather than connecting with websockets; there's a few options for singular / h2r specifically.</p>
<p>For some images provided in the outgoing data-structure, the assumed host location for certain files/images, if none provided, should be <code>https://socialstream.ninja/</code>.</p>
<p>If wanting to connect to the websocket server, to publish or listen to messages, you can refer to the code for actual examples. However, a simple way to listen for messages broadcasted by the extension is with <code>wss://io.socialstream.ninja/join/SESSIONIDHERE/4</code>, which implies joining the room with our session ID as the name, and then subscribing to channel 4 for messages. <code>wss://io.socialstream.ninja/join/SESSIONIDHERE/1/2</code> on the other hand would listen on channel 1, and publish to channel 2.</p>
<h5 id="singular-live">Singular Live</h5>
<p><code>&singular=XXXXXXX</code> will send selected messages (via the dock page) to singular live for featured message overlay. The target address will be: <code>https://app.singular.live/apiv1/datanodes/XXXXXXX/data</code></p>
<p>This parameter is added to the dock page to use.</p>
<h5 id="h2r">H2R</h5>
<p><code>&h2r=XXXXXXX</code> will send selected messages (via the dock page) to a local H2R server using its POST data structure. The target address will be: <code>"http://127.0.0.1:4001/data/XXXXXXX</code></p>
<p>You can manually set a custom H2R URL though with <code>&h2rurl</code> though, which will override the default one.</p>
<p>These parameters are added to the dock page to use.</p>
<h5 id="generic-post--put">Generic POST / PUT</h5>
<p>These options will send selected featured messages (via the Dock page) to a remote web server; the default URL is "<a href="http://127.0.0.1">http://127.0.0.1</a>"</p>
<p>A generic JSON-POST can be made using <code>&postserver</code>, with the address provided
<code>&postserver=https://domain.com/input-source</code></p>
<p>A generic JSON-PUT can be made using <code>&putserver</code>, with the address provided. There isn't much difference between POST and PUT, but some sites are picky.
<code>&putserver=https://domain.com/input-source</code></p>
<p>In these cases, the JSON being delivered is in the Social Stream Ninja data-structure. Example usage is as follows:</p>
<p><code>https://socialstream.ninja/dock?session=XXXXXX&postserver=https://127.0.0.1/messageingest/?socialstream</code></p>
<h4 id="inbound-third-party-donation-support">Inbound third-party donation support</h4>
<h5 id="stripe-webhook-donation-support">Stripe webhook donation support</h5>
<p>If you create a Stripe payment link (eg: <a href="https://donate.stripe.com/YYYYYYYYYYYY">https://donate.stripe.com/YYYYYYYYYYYY</a>), you can have successful payments show up in Social Stream Ninja. This is a great way to collect donations from viewers of your stream without needing to use middleware for payment processing.</p>
<p>To get started, after creating a Stripe payment link, create a Stripe webhook that listens for the event <code>checkout.session.completed</code>. Have the webhook point to: <code>https://io.socialstream.ninja/XXXXXX/stripe</code>, where XXXXXX is your Social Stream Ninja session ID. You don't need to worry about the verification signatures or API tokens in Stripe since we won't be verifying the payments. Of course, keep your session ID private as a result, else someone will be able to spoof fake donations to your end point.</p>
<p>If you wish to ask the payer for a name, include a custom field called "Display Name" or "Username" when creating your Stripe payment link. You can also include a field called "Message", which will allow the payer an opportunity to leave a custom message. The donation amount and current type should be dervived from the payment automatically, but some rare exotic currencies may not always show up with the right decimal place -- just keep that in mind.</p>
<p>Lastly, to allow these events to show up in the Social Stream Ninja dock, add &server to the dock URL; this will have the dock start listening for incoming messages from the webhook/api server. You can always test that the workflow is working using Stripe's "Test mode"; just spam 424242.. etc for the credit card number, expiration, cvc, etc, when using the test mode, rather than a valid credit card.</p>
<p><img src="https://github.com/steveseguin/social_stream/assets/2575698/29bab9b6-8fb7-482d-87d1-2b7f2bd74f9f" alt="image"></p>
<p><img src="https://github.com/steveseguin/social_stream/assets/2575698/3f31974c-6bbb-4ed0-bc7c-4d27f7c3103b" alt="image"></p>
<h5 id="ko-fi-webhook-donation-support">Ko-Fi webhook donation support</h5>
<p>This is very simliar to the Stripe support method, as seen above.</p>
<p>To setup, sign into your Ko-Fi account, go to <a href="https://ko-fi.com/manage/webhooks">https://ko-fi.com/manage/webhooks</a></p>
<p>Add <code>https://io.socialstream.ninja/XXXXXXXX/kofi</code> to the Webhook URL text field, where you replace XXXXXXXX with your Social Stream Ninja session ID.</p>
<p><img src="https://github.com/steveseguin/social_stream/assets/2575698/9119d86a-d452-4658-b1c5-383f5b16fc9d" alt="image"></p>
<p>On your <code>dock.html</code> page, append &server to the URL (at the end is fine). This has the dock connecting to the Social Stream Ninja API service, which is where our Ko-Fi notifications will come from.</p>
<p><img src="https://github.com/steveseguin/social_stream/assets/2575698/d4669e90-1019-4b6d-a809-ed1483f0b770" alt="image"></p>
<p>You can then press the Send Single Donation Test button.</p>
<p><img src="https://github.com/steveseguin/social_stream/assets/2575698/73ba4b80-c599-45f6-85df-6ff629a3e6a5" alt="image"></p>
<p>Please note, do not share your Social Stream Ninja session ID with others as they will be able to create fake donations to Social Stream Ninja via posting to the API.</p>
<h3 id="text-to-speech">Text to speech</h3>
<p>Text messages can be converted to speech for free, assuming your system supports TTS. On my Windows machine running Chrome/Edge/OBS, it works just fine. I have it set to English-US by default, but you can change the language to something else by editing the URL and adjusting the language code.</p>
<p>ie: <code>index.html?session=XXXXXX&speech=en-US</code> or <code>socialstream.ninja/?session=xxx&&speech=en-US</code></p>
<p>Please visit <a href="https://socialstream.ninja/tts">https://socialstream.ninja/tts</a> for a list of available speech options for your specific browser + system. Google Chrome and MS Edge will offer both local and cloud-hosted language options, while "free" open-source browsers, like Chromium or Firefox may only have access to local system languages or none at all. Local options should work within the OBS browser source, such as the ones shown in the image below, but non-local free options will need to be used via Chrome or Edge.</p>
<p><img src="https://github.com/steveseguin/social_stream/assets/2575698/228ff1ca-ad7b-4d73-b3a6-2ff2e01c6cca" alt="image"></p>
<p>You can sometimes install additional local languages if on Windows. See: <a href="https://support.microsoft.com/en-us/windows/download-language-pack-for-speech-24d06ef3-ca09-ddcc-70a0-63606fd16394">https://support.microsoft.com/en-us/windows/download-language-pack-for-speech-24d06ef3-ca09-ddcc-70a0-63606fd16394</a></p>
<p><img src="https://user-images.githubusercontent.com/2575698/165753730-374498e7-7885-49ef-83ba-7fe2acde26ee.png" alt="image"></p>
<p>Please note that when using this free TTS approach, the audio will play out the default system audio output device. This might be a problem if using OBS for capture, as you'll need to use a virtual audio cable to capture the audio output of the system output and route it back into OBS for capture. Another user mentioned they were able to capture the TTS audio in OBS by selecting <code>explorer.exe</code> in the system application recorder.</p>
<p>If it's too complicated to use the built-in free TTS, using the premium Google Cloud / ElevenLabs TTS option (mentioned below) would be a great non-free solution to this issue. The paid options play out as browser tab audio, not system audio. See the related issue here: <a href="https://github.com/w3c/mediacapture-output/issues/102">https://github.com/w3c/mediacapture-output/issues/102</a></p>
<p>If loading the app in the Chrome/Edge/Firefox browser, you will need to "click" the web page first before audio will play. This isn't the case with OBS, but most browsers require the user interact with the website on some level before it will play audio. Please keep this in mind when testing things.</p>
<p>There is a toggle in the dock to turn off and on the text-to-speech; turning it off whill automatically stop any audio playout. Still, be careful when using text-to-speech with the dock, as viewers can exploit it to have your system read out unwanted things on air.</p>
<h4 id="installing-different-language-speech-packs">Installing different language-speech packs</h4>
<p>By default, the list of support languages on your computer could be slim. To add more speech options for different langauges, you'll need to install them.</p>
<p>see: <a href="https://support.microsoft.com/en-us/windows/download-language-pack-for-speech-24d06ef3-ca09-ddcc-70a0-63606fd16394">https://support.microsoft.com/en-us/windows/download-language-pack-for-speech-24d06ef3-ca09-ddcc-70a0-63606fd16394</a> for details</p>
<p>There's a simplified test app for text-to-speech here also, that might also help try different languages on the fly:
<a href="https://mdn.github.io/dom-examples/web-speech-api/speak-easy-synthesis/">https://mdn.github.io/dom-examples/web-speech-api/speak-easy-synthesis/</a></p>
<p>You can manaul set the pitch, volume, rate, and even voice-name with the below URL parameters. The voice just matches on a partial word, so "siri", "google", "bob", or whatever is being used will work. This still assumes the language selected also matches. <code>&speech=en</code> (first english to match), <code>&speech=en-US</code> (default), or <code>&speech=fr-CA</code> can specify the language, for example.</p>
<pre><code>&pitch=1
&volume=1
&voice=google
&rate=1
</code></pre>
<h4 id="premium-tts-voice-options">Premium TTS voice options</h4>
<h5 id="google-cloud-tts">GOOGLE CLOUD TTS</h5>
<p>I've added support for Google Cloud Text to Speech API, but you must use your own API key to use this feature, as it is expensive to use. </p>
<p>Go to <a href="https://cloud.google.com/text-to-speech">https://cloud.google.com/text-to-speech</a> -> Enable the service, and then get an API key.</p>
<p><img src="https://user-images.githubusercontent.com/2575698/180443408-5cc0f7a9-c015-420d-9541-fd94a520ef25.png" alt="image"></p>
<p>This premium text-to-speech is supported on the index.html (the featured chat overlay) and dock.html page. If you stop the TTS with the button in the dock's menu, it will stop playback immediately in the dock. It will also delete any queued messages to be spoken.</p>
<p>You need at least &speech and &ttskey to enable the premium TTS, but there are customizations:</p>
<pre><code>&volume=1
&voice=en-GB-Standard-A
&gender=FEMALE
&speech=en-us
&ttskey=XXXXXXX
</code></pre>
<p>See the Google Cloud doc for more help</p>
<h5 id="eleven-labs-tts">Eleven Labs TTS</h5>
<p>If you want a different set of voices, or wish to train your own, ElevenLabs.io has a TTS service that you can try. There's a "free" version you can get started testing with, which just needs you to create an account there and get an API key from your profile settings there. You may need to provide attribution as required, for the free tier?</p>
<p>Anyways, documentation on getting start with finding a voice you want to use and testing your API key:
API Social Stream Ninja is using: <a href="https://api.elevenlabs.io/docs#/text-to-speech/Text_to_speech_v1_text_to_speech__voice_id__stream_post">https://api.elevenlabs.io/docs#/text-to-speech/Text_to_speech_v1_text_to_speech__voice_id__stream_post</a>
Available voices: <a href="https://api.elevenlabs.io/docs#/voices/Get_voices_v1_voices_get">https://api.elevenlabs.io/docs#/voices/Get_voices_v1_voices_get</a></p>
<p>To use this with Social Stream Ninja, you'll need to be using the featured-chat index.html or dock.html page, and you'll need to provide your api key there.</p>
<p>Example URL with options <code>https://socialstream.ninja/index.html?session=SESSIONIDHERE&tts&elevenlabskey=YOURELEVENLABSAPIKEYHERE&latency=4&voice=VR6AewLTigWG4xSOukaG</code></p>
<ul>
<li>&tts is also required to enable TTS in general</li>
<li>&voice={VOICEIDHERE} , is the voice ID you want to use.</li>
<li>&latency={N}, where N can be 0,1,2,3, or 4. 0 is high latency, but better quality. Default is 4 (fastest)</li>
<li>&elevenlabskey={APIKEYHERE} , don't share this API key, but this is needed to use the service and to specify that you want to use elevenlabs for TTS</li>
</ul>
<p>If you stop the TTS with the button in the dock's menu, it will stop playback immediately in the dock. It will also delete any queued messages to be spoken. </p>
<p>Please NOTE: Make sure to CLICK on the browser page after it loads, else audio may not work in the browser. Browsers require user-gesture detection before audio can auto-play. OBS Studio's browser source and the Electron Capture app are exceptions to this rule.</p>
<h3 id="branded-channel-support">Branded channel support</h3>
<p>There is a toggle that lets you show the source of the chat messages.</p>
<ul>
<li>&branded will show the channel-icon; Youtube and Twitch channels supported. Use with the dock or index file.</li>
<li>&showsource can be added to the index.file, to show the main site the source is from; ie: Youtube, Facebook.</li>
</ul>
<p><img src="https://user-images.githubusercontent.com/2575698/166864138-00cd1e1c-2149-473f-be8d-d07a8d400c07.png" alt="image"></p>
<h3 id="random-other-commands-not-documented-elsewhere">Random other commands not documented elsewhere</h3>
<ul>
<li><p>You can exclude certain sources from appearing in the dock with the &exclude option</p>
<ul>
<li>ie: dock.html?session=xxx&exclude=youtube,twitch,facebook</li>
</ul>
</li>
<li><p>You can combine multiple docks into one, if for example you have multiple extensions capturing chat, and want to view it all one a single computer</p>
<ul>
<li>ie: dock.html?session=aaaaa,bbbbb</li>
</ul>
</li>
<li><p>You can filter out certain messages marked as "events" in the dock using &filterevents</p>
<ul>
<li>ie: dock.html?session=xxx&filterevents=joined</li>
</ul>
</li>
<li><p>the Filter option in the dock supports <code>!</code> to denote opposite, such as <code>source:!youtube</code>, so only filter for sources that are not youtube.</p>
</li>
</ul>
<h3 id="known-issues-or-solutions">Known issues or solutions</h3>
<h4 id="chat-stops-when-put-in-the-background-or-minimized">Chat stops when put in the background or minimized</h4>
<ul>
<li><p>Browser may pause non-visible windows, such as the chat streams Social Stream Ninja grabs from, and so you may need to disable this behaviour in your browser. To do so, "Disable" the option located at <code>chrome://flags/#enable-throttle-display-none-and-visibility-hidden-cross-origin-iframes</code>. Also "Disable" the flag <code>chrome://flags/#calculate-native-win-occlusion</code>. Restart the browser after saving the changes.</p>
</li>
<li><p>Avoid minimizing any windows. Things work best if windows are kept visible and open, but if you need to put them in the background, don't minimize them at least. </p>
</li>
<li><p>Browsers may also sometimes stop tabs/windows after an hour of inactivity. Disable any option in your browser under <code>chrome://settings/performance</code> related to performance throttling or background tabs, such as "Throttle Javascript timers in background".</p>
</li>
<li><p>Try to keep the chat window and dock page active and if possible, even partially visible on screen. If the windows are hidden or minimized, they may stop working. This is also true if the scroll bar for the chat window is not at the bottom; sometimes messages won't load unless you are seeing the newest messages. </p>
</li>
<li><p>Another option, if chat messages stop once put in them in background, if using Windows, is to do Win + Tab, and have two virtual Desktops on your PC. Put the chat windows into one virtual desktop, and use OBS in the other. Win+Tab can let you switch between desktops/windows.</p>
</li>
<li><p>You can also try the Social Stream Ninja Standalone desktop app, as that has more controls and will avoid common throttling / visibility issues found while using Chrome</p>
</li>
<li><p>You can also download an application that can "pin" the chat windows, so they remain on top and visible. The windows can be made very small in those cases, and just push to the side.</p>
</li>
</ul>
<h4 id="blue-bar-appears-or-chat-responder-not-working">Blue bar appears or chat responder not working</h4>
<p>If the auto responder doesn't work -- you see a blue bar, but nothing happens, there's a couple things to do.</p>
<ul>
<li>make sure if using Youtube/Twitch that the pop out window is open</li>
<li>Avoid Firefox, as it will only work with Chromium-based apps (or the standalone app)</li>
<li>go to <code>chrome://apps</code> and remove the Youtube(s) apps that might appear. You can remove them all really if none are required.</li>
<li>Make sure you have permission to post into the chat first -- sometimes you need to be a subscriber for example to send chat messages.</li>
</ul>
<p><img src="https://user-images.githubusercontent.com/2575698/146602513-e3b7e69c-19fa-4e58-b907-6f08b3f873e0.png" alt="image"></p>
<ul>
<li>If the blue bar warning about Debugging mode is a problem, start Chrome with this command line flag: <code>--silent-debugger-extension-api</code></li>
</ul>
<p><img src="https://user-images.githubusercontent.com/2575698/196629133-6c06fedb-9f22-40aa-8031-d7f4c681ad95.png" alt="image"></p>
<h4 id="cant-export-settings-or-save-files">Can't export settings or save files</h4>
<ul>
<li>If you can't save to disk, like export the settings to disk, ensure your browser allows the <code>File System Access API</code></li>
</ul>
<p>In Brave, this can be enabled via <code>brave://flags/#file-system-access-api</code> ; open that link and enable the setting (then restart)</p>
<h4 id="other-issues">Other issues</h4>
<ul>
<li><p>If using OBS Studio on macOS or Linux, for some reason this extension will not work if hosted locally on your drive, so custom CSS needs to happen via the browser source style section. It works great on PC locally, and when hosted on socialstream.ninja, but locally on mac, it does not seem supported. This is an issue you'll need to take up with the OBS developers.</p>
</li>
<li><p>For discord, slack, and telegram not working, for security reasons, you need to enable the TOGGLE switch in the settings to enable.</p>
</li>
<li><p>Make sure your session ID matches the dock.html page and the value inside the extension; if they don't match, things work work</p>
</li>
<li><p>To set the Session ID to your own value, go to Extensions settings to set it. On Chrome: Settings -> Extensions -> Social Stream Ninja -> Details -> Extension options. </p>
</li>
<li><p>Try refreshing the chat page if things stop working; sometimes refreshing the page will retrigger the code and bypass any errors. This is particularly try if you install or refresh the extension after the chat page has already been loaded.</p>
</li>
</ul>
<h3 id="requesting-a-site">Requesting a site</h3>
<p>You can make a request here on Github as an issue ticket, or join the Discord server at <a href="https://discord.socialstream.ninja">https://discord.socialstream.ninja</a> and request there.</p>
<p>Not all requested sites can or will be supported. Steve generally will add support for publicly accessible social chat sites that have a significantly-large community; it's ultimately up to the decretion of Steve though on what he wants to add or has time to add. Code contributions from others that add new site integration or features are normally welcomed, but sites/features that may violate Canadian laws, fail to meet quality standards, or for any other reason, may possibly not be merged or accepted. In these cases you may need to self-host or fork the repo, maintaining your own copy with said changes instead.</p>
<p>There is no guarentee that a site that gets added will continue to be supported over time. Steve also doesn't accept payment for adding an integration or for support.</p>
<h3 id="adding-sites-yourself">Adding sites yourself</h3>
<p>I have a video walk-thru on how I added a simple social site to Social Stream Ninja: <a href="https://www.youtube.com/watch?v=5LquQ1xhmms">https://www.youtube.com/watch?v=5LquQ1xhmms</a></p>
<p>You can also refer to some of my code commits, where you can see which changes I made to add support for any specific site.</p>
<p>ie: <code>https://github.com/steveseguin/social_stream/commit/942fce2697d5f9d51af6da61fc878824dee514b4</code></p>
<p>For a simple site, a developer should need just 30 minutes to an hour to get a site supported. A more complicated and tricky site may take a few hours or longer, depending on the developer's skill.</p>
<h3 id="support">Support</h3>
<p>You can find me on discord over at <a href="https://discord.socialstream.ninja">https://discord.socialstream.ninja</a> or <a href="https://discord.gg/vFU8AuwNf3">https://discord.gg/7U4ERn9y</a>, offering free support in channel #chat.overlay-support </p>
<p>Feedback and feature requests are welcomed. Please also make a Github issue if you're not a fan of Discord, but still need to report a bug or feature request.</p>
<h3 id="donations">Donations</h3>
<p>I condemn Russia's brutal invasion of Ukraine. 💙💛 Please consider supporting or donating to Ukraine instead: <a href="https://war.ukraine.ua/support-ukraine/">https://war.ukraine.ua/support-ukraine/</a></p>
<h3 id="icons">Icons</h3>
<p>I do not claim rights of all the icons distributed. While I made some of the icons, trademarks and logos of third party companies/services are the rights of those respectivitive entities. Use them according to the terms that those entities may offer them under.</p>
<p>Some icons used are licensced as attribution-required:
<a href="https://www.flaticon.com/free-icons/communication" title="communication icons">Communication icons created by Freepik - Flaticon</a></p>
<h3 id="credit">Credit</h3>
<p>This project contains inspiration by my other project, chat.io.socialstream.ninja, which was a derivation of another Youtube-specific chat widget, which was inspired by the stylings of other featured-chat code sample, of which that was also inspired by existing chat overlay designs. May the many new innovations of this project inspire the future foundation of other awesome projects as well.</p>
<h3 id="contributors-to-this-project">Contributors to this project</h3>
<a href="https://github.com/steveseguin/social_stream/graphs/contributors">
<img src="https://contrib.rocks/image?repo=steveseguin/social_stream">
</a>
</section>
<footer>
<p>Join our community for free support on <a href="https://discord.socialstream.ninja" target="_blank">Discord</a>.</p>
</footer>
<script>
function scrollToAnchor(hash, retryCount = 0, maxRetries = 3) {
const targetId = hash.replace('#', '');
let targetElement = document.getElementById(targetId);
if (!targetElement) {
const headings = document.querySelectorAll('h1, h2, h3, h4, h5, h6');
for (const heading of headings) {
try {
const headingId = heading.textContent.toLowerCase()
.replace(/[^\w\s-]/g, '')
.replace(/\s+/g, '-');
if (headingId === targetId) {
targetElement = heading;
break;
}
} catch(e) {}
}
}
if (!targetElement) return;
const images = document.querySelectorAll('#markdown img');
const imagePromises = Array.from(images).map(img =>
img.complete ? Promise.resolve() :
new Promise(resolve => {
img.onload = img.onerror = resolve;
})
);
Promise.all(imagePromises).then(() => {
setTimeout(() => {
const offset = targetElement.getBoundingClientRect().top + window.scrollY - 20;
window.scrollTo({
top: offset,
behavior: 'smooth'
});
if (Math.abs(targetElement.getBoundingClientRect().top) > 50 && retryCount < maxRetries) {
setTimeout(() => scrollToAnchor(hash, retryCount + 1, maxRetries), 500);
}
}, 100);
});
}
const REQUIRED_SCRIPTS = [
'./thirdparty/marked.umd.min.js',
'./thirdparty/index.umd.min.js'
];
function loadScripts(scripts, callback) {
let loaded = 0;
scripts.forEach(src => {
const script = document.createElement('script');
script.src = src;
script.onload = () => {
loaded++;
if (loaded === scripts.length) callback();
};
document.head.appendChild(script);
});
}
if (location.protocol.startsWith('http')) {
document.addEventListener("DOMContentLoaded", () => {
loadScripts(REQUIRED_SCRIPTS, () => {
const gfmHeading = markedGfmHeadingId.gfmHeadingId();
gfmHeading.name = 'gfm-heading-id';
marked.setOptions({
headerIds: true,
mangle: false
});
marked.use({ extensions: [gfmHeading] });
fetch('./README.md')
.then(response => {
if (!response.ok) throw new Error('Failed to fetch README.md');
return response.text();
})
.then(text => {
document.getElementById('markdown').innerHTML = marked.parse(text);
if (window.location.hash) {
scrollToAnchor(window.location.hash);
}
})
.catch(error => console.error('Error loading the README:', error));
window.addEventListener('hashchange', () => {
if (window.location.hash) {
scrollToAnchor(window.location.hash);
}
});
});
});
}
</script>
</body>
</html>