Coder Social home page Coder Social logo

mpv-twitch-chat's Introduction

Show Twitch chat messages as subtitles when watching Twitch VOD with mpv.

mpv internally uses youtube-dl to handle Twitch VOD URL. In addition to the regular video track, it also adds a "rechat" subtitle track. This track points to the Twitch API videos/<video_id>/comments, which contains the full transcript of a VOD's chat messages in JSON. Unfortunately, mpv can't directly consume the JSON as subtitle. This script converts it into a SubRip subtitle track so that mpv can directly display the chat messages.

Note that since subtitle is text-based only, all Twitch emotes are shown as text.

The API this script uses to get the chat data is undocumented and not intended for public use, according to Twitch. It could change or be broken at any moment, and there is no guarantee from the author. Use at your own risk.

Features

  • Configurable to show commenter's name.
  • Configurable to show colored messages.
  • Configurable message duration.
  • Friendly to mpv's built-in subtitle options.

Requirement

  • curl, which should be preinstalled in most operating systems

Install

Best way to install is git clone this repo in mpv's "scripts" directory. This approach allows easy update by simply git pull.

Alternatively, one can download the repo as zip and extract to mpv's "scripts" directory. Updates must be made manually.

Script option file should be placed in mpv's script-opts directory as usual. Options are explains in the script file.

User should specify a working Twitch API client ID in the option file.

Usage

To activate the script, play a Twitch VOD and switch on the "rechat" subtitle track. The script will replace it with its own subtitle track.

You can use mpv's auto profiles to conditionally apply special subtitle options when Twitch VOD is on. For example,

[twitch]
profile-cond=get("path", ""):find("^https://www.twitch.tv/") ~= nil
profile-restore=copy-equal
sub-font-size=30
sub-align-x=right
sub-align-y=top

makes the Twitch chat subtitles smaller than default, and moved to the top right corner.

Screenshot

Screenshot

mpv-twitch-chat's People

Contributors

crendking avatar lukasfink1 avatar metroite avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

mpv-twitch-chat's Issues

This API does not exist

When playing a VOD is gives me this error, How do i fix this?

[mpv_twitch_chat] Failed to download comments JSON: {"error":"Not Found","status":404,"message":"This API does not exist"}

Arbitrarily, Lua throws `a nil value` and ceases message generation

Initially I thought this had something to do with seeking backwards, but I was able to trigger this without seeking more than once... Here's a couple examples of the effect:

  1. Seeking backwards seems to cause it more often.
  2. It's possible to seek only forward five seconds and get the same effect.
  3. Or it'll just happen after about 6 or so minutes of watching.

Here's an mpvlog.txt.
Particularly:

[ 147.544][w][mpv_twitch_chat_master] stack traceback:
[ 147.544][w][mpv_twitch_chat_master] 	...rzap/.config/mpv/scripts/mpv-twitch-chat-master/main.lua:140: in function 'load_twitch_chat'
[ 147.544][w][mpv_twitch_chat_master] 	...rzap/.config/mpv/scripts/mpv-twitch-chat-master/main.lua:227: in function 'timer_callback'
[ 147.544][w][mpv_twitch_chat_master] 	...rzap/.config/mpv/scripts/mpv-twitch-chat-master/main.lua:231: in function 'cb'
[ 147.544][w][mpv_twitch_chat_master] 	mp.defaults:361: in function 'process_timers'
[ 147.544][w][mpv_twitch_chat_master] 	mp.defaults:530: in function 'dispatch_events'
[ 147.544][w][mpv_twitch_chat_master] 	mp.defaults:503: in function <mp.defaults:502>
[ 147.544][w][mpv_twitch_chat_master] 	[C]: in ?
[ 147.544][w][mpv_twitch_chat_master] 	[C]: in ?
[ 147.544][f][mpv_twitch_chat_master] Lua error: ...rzap/.config/mpv/scripts/mpv-twitch-chat-master/main.lua:140: attempt to index field 'comments' (a nil value)
[ 147.544][d][mpv_twitch_chat_master] Exiting...

New into MPV

Hi, I'm new into MPV and more to lua script, so I need some help. I've downloaded a twitch vod, and also its chat on a txt file. Both have the same name, with their respective extensions (VOD.mp4 and VOD.txt). I'm on Win 7 x64 btw. I've created the folders "scripts" and "script-opts" inside MPV, then I've renamed the script from "main.lua" to "Twitch-chat.lua", and put it on the "script" folder. Seems that I need to put a config file on the "script-opts" file, but a example will be appreciated.
Cheers.

Script crashes when loading media with external, embedded, or drag'n'dropped subtitles

Example Youtube video with external EN sub loaded via ytdl_hook.lua:

[ C:\Users\garoto\AppData\Roaming\mpv\scripts ]

> mpv --msg-level=all=no,ytdl_hook=trace,twitch_chat=trace --sid=1 --no-config --script=twitch_chat https://www.youtube.com/watch?v=vqduGTChT5U
[ytdl_hook] Loading lua script @ytdl_hook.lua...
[ytdl_hook] loading mp.defaults
[twitch_chat] Loading lua script twitch_chat/main.lua...
[ytdl_hook] loading @ytdl_hook.lua
[ytdl_hook] reading options for ytdl_hook
[ytdl_hook] script-opts/ytdl_hook.conf not found.
[twitch_chat] loading mp.defaults
[twitch_chat] loading file twitch_chat/main.lua
[twitch_chat] reading options for twitch_chat
[twitch_chat] script-opts/twitch_chat.conf not found.
[ytdl_hook] ytdl:// hook
[ytdl_hook] not a ytdl:// url
[ytdl_hook] full hook
[ytdl_hook] No youtube-dl found with path youtube-dl.exe in config directories
[ytdl_hook] Running: youtube-dl --no-warnings -J --flat-playlist --sub-format ass/srt/best --format bestvideo+bestaudio/best --all-subs --no-playlist -- https://www.youtube.com/watch?v=vqduGTChT5U
[ytdl_hook] youtube-dl succeeded!
[ytdl_hook] ytdl parsing took 1.756 seconds
[ytdl_hook] No fragments to join into EDL
[ytdl_hook] No fragments to join into EDL
[ytdl_hook] format selection: youtube-dl (separate)
[ytdl_hook] streamurl: edl://!new_stream;!no_clip;!no_chapters;%980%https://r2---sn-b8u-jo4e.googlevideo.com/videoplayback?expire=1626824626&ei=Ugv3YOWdJ53s1sQPj--AsA4&ip=<redacted>&id=o-ALRabbxDmbkZR8mnyCI8P0sTz0WbXtKzwKWvbttNa4vy&itag=315&aitags=133%2C134%2C135%2C136%2C160%2C242%2C243%2C244%2C247%2C278%2C298%2C299%2C302%2C303%2C308%2C315&source=youtube&requiressl=yes&mh=jb&mm=31%2C29&mn=sn-b8u-jo4e%2Csn-bg07dn6l&ms=au%2Crdu&mv=m&mvi=2&pl=21&initcwndbps=938750&vprv=1&mime=video%2Fwebm&ns=7u_eeaB3Xf99erQbqc9YpAgG&gir=yes&clen=4435454665&dur=1395.366&lmt=1584828776934343&mt=1626802847&fvip=2&keepalive=yes&fexp=24001373%2C24007246&c=WEB&txp=5531432&n=B3QU3os08eotRdn&sparams=expire%2Cei%2Cip%2Cid%2Caitags%2Csource%2Crequiressl%2Cvprv%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&sig=AOq0QJ8wRAIgHAogYb9v4IaN5AffcL2Jbqo9uMI-llztcioIT-OhPMsCIH7GhE5QPZp-MV0Dcs0JnPjOlEJNFcMc7w6aYq5DCvcb&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AG3C_xAwRAIgd1X7mRzdH11gUD5Ut55IWKLDwB7hFjEdW81Z5W2xjugCIHy6QcrU3i9rU61457A9j--XAr6MHX3izDrdY5GeKxFu;!new_stream;!no_clip;!no_chapters;%882%https://r2---sn-b8u-jo4e.googlevideo.com/videoplayback?expire=1626824626&ei=Ugv3YOWdJ53s1sQPj--AsA4&ip=<redacted>&id=o-ALRabbxDmbkZR8mnyCI8P0sTz0WbXtKzwKWvbttNa4vy&itag=140&source=youtube&requiressl=yes&mh=jb&mm=31%2C29&mn=sn-b8u-jo4e%2Csn-bg07dn6l&ms=au%2Crdu&mv=m&mvi=2&pl=21&initcwndbps=938750&vprv=1&mime=audio%2Fmp4&ns=7u_eeaB3Xf99erQbqc9YpAgG&gir=yes&clen=22584635&dur=1395.426&lmt=1584824607623586&mt=1626802847&fvip=2&keepalive=yes&fexp=24001373%2C24007246&c=WEB&txp=5531432&n=B3QU3os08eotRdn&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cvprv%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&sig=AOq0QJ8wRQIgK0yoBx-_3QUEbVEfPMLG65OH0eXP2B1U3dIshQuUtm0CIQCElNXRHn44VsB-B62djxrttEKQsCTYh6gxeRuum-AwAw%3D%3D&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AG3C_xAwRAIgd1X7mRzdH11gUD5Ut55IWKLDwB7hFjEdW81Z5W2xjugCIHy6QcrU3i9rU61457A9j--XAr6MHX3izDrdY5GeKxFu;!global_tags,ytdl_description=%475%Diving into DOOM Eternal! Taking a look at the improvements over Doom 2016, how it's inspired by the classic games, what kind of demonic nonsense ensues, and all kinds of eternally relevant stuff. RIP AND TEAR folks!
[ytdl_hook]
[ytdl_hook] Review code was provided by the publisher. Not sponsored, no payments exchanged, all opinions are my own.
[ytdl_hook]
[ytdl_hook] ? LGR links:
[ytdl_hook] https://twitter.com/LazyGameReviews
[ytdl_hook] https://facebook.com/LazyGameReviews
[ytdl_hook] https://patreon.com/LazyGameReviews
[ytdl_hook]
[ytdl_hook] #LGR #DoomEternal #Review,upload date=%8%20200317,dislikes=%3%606,likes=%5%25493,views=%6%632221,channel_url=%56%https://www.youtube.com/channel/UCLx053rWZxCiYWsBETgdKrQ,uploader=%3%LGR
[ytdl_hook] adding subtitle [en]
[ytdl_hook] script running time: 1.759 seconds
[twitch_chat]
[twitch_chat] stack traceback:
[twitch_chat]   [string "twitch_chat/main.lua"]:158: in function 'timer_callback'
[twitch_chat]   [string "twitch_chat/main.lua"]:178: in function 'prop'
[twitch_chat]   mp.defaults:406: in function 'handler'
[twitch_chat]   mp.defaults:509: in function 'call_event_handlers'
[twitch_chat]   mp.defaults:554: in function 'dispatch_events'
[twitch_chat]   mp.defaults:502: in function <mp.defaults:501>
[twitch_chat]   [C]: at 0x00312840
[twitch_chat]   [C]: at 0x00311250
[twitch_chat] Lua error: [string "twitch_chat/main.lua"]:67: attempt to concatenate upvalue 'twitch_comments_url' (a nil value)
[twitch_chat] Exiting...
[ytdl_hook] Exiting...

The crash happens at a different spot when the subtitle is embedded in the media:

> mpv --no-config --script=twitch_chat "G:\Torrents\x264\Cowboy Bebop Remastered 01-26 [Dual Audio] H264\[KB]_Cowboy_Bebop_Remastered_06.DVD_(H264.Dual_AC3)[80AA5E1B].mkv"
 (+) Video --vid=1 (*) 'Session #6: Sympathy for the Devil' (h264 704x480 23.976fps)
 (+) Audio --aid=1 --alang=jpn (*) '6ch Dolby AC3' (ac3 6ch 48000Hz)
     Audio --aid=2 --alang=eng '2ch Dolby AC3' (ac3 2ch 48000Hz)
 (+) Subs  --sid=1 --slang=eng (*) 'Styled Subs (ASS)' (ass)
[twitch_chat]
[twitch_chat] stack traceback:
[twitch_chat]   mp.defaults:406: in function 'handler'
[twitch_chat]   mp.defaults:509: in function 'call_event_handlers'
[twitch_chat]   mp.defaults:554: in function 'dispatch_events'
[twitch_chat]   mp.defaults:502: in function <mp.defaults:501>
[twitch_chat]   [C]: at 0x00312840
[twitch_chat]   [C]: at 0x00311250
[twitch_chat] Lua error: [string "twitch_chat/main.lua"]:174: attempt to index local 'sub_filename' (a nil value)
AO: [wasapi] 48000Hz 5.1(side) 6ch float
VO: [gpu] 704x480 => 704x528 yuv420p
AV: 00:00:00 / 00:24:39 (0%) A-V:  0.000

Exiting... (Quit)

New to MPV, can't seem to get it working

  • I've installed curl properly - checked with the version command
  • I've put the lua scipt file inside the mpv/scripts folder in roaming
  • I've created a twitch.conf file inside the script-opts folder also in roaming
  • I've put a twitch_client_id which I got by creating a new application in dev.twitch
  • I've put the contents of the config profile in the 'Usage' section inside the mpv config file in 'portable_config' in my mpv directory

I honestly don't know what I'm doing wrong. I do get a subtitle track, but when I switch to it nothing happens (I'm using yt-dlp if that's important. Also have streamlinks installed.). Any help would be much appreciated. Apologies if this isn't the standard format for a github issue report.

script-opts seem to be ignored

I'v got the chat working but it seems scipt-opts are ignored.

I cloned the repo to the mpv scripts dir so that the script is located at ~/.config/mpv/scripts/mpv-twitch-chat/main.lua and I have tried putting following script opts file at ~/.config/mpv/script-opts/twitch.conf:

twitch_client_id: 'clientid'
show_name: true
color: false
duration_multiplier: 20
max_duration: 60
max_message_length: 40
fetch_aot: 1

Although show_name is set to true names are not shown. I also tried passing a single option via --script-opts=show_name=true command line parameter, but same result.

My ~/.config/mpv/mpv.conf:

[twitch]
profile-cond=get("path", ""):find("^https://www.twitch.tv/") ~= nil
profile-restore=copy-equal
sub-font-size=30
sub-align-x=right
sub-align-y=top
slang=rechat

Also what's strange is if I remove my twitch.conf altogether, the chat subtitles still work, so it seems the twitch_client_id isn't even that necessary.

Here's the output of mpv during playback, there are no apparent errors:

[auto_profiles] Applying auto profile: twitch 
 (+) Video --vid=1 (h264 1280x720)
 (+) Audio --aid=1 (aac 2ch 48000Hz)
 (+) Subs  --sid=1 --slang=rechat 'json' (null) (external)
Track removed:
 (+) Video --vid=1 (h264 1280x720)
 (+) Audio --aid=1 (aac 2ch 48000Hz)
Using hardware decoding (vaapi).
AO: [pulse] 48000Hz stereo 2ch float
VO: [gpu] 1280x720 vaapi[nv12]
AV: 03:56:08 / 04:36:41 (85%) A-V:  0.011 ct:  0.058 Dropped: 2 Cache: 6.1s/2MB
Track added:
 (+) Video --vid=1 (h264 1280x720)
 (+) Audio --aid=1 (aac 2ch 48000Hz)
 (+) Subs  --sid=1 'Twitch Chat' (subrip) (external)
AV: 03:58:48 / 04:36:41 (86%) A-V:  0.000 ct:  0.069 Dropped: 2 Cache: 354s/126MB

script doesn't work for Lua version < 5.2

I get this error when running mpv

[mpv_twitch_chat] 
[mpv_twitch_chat] stack traceback:
[mpv_twitch_chat]       [C]: ?
[mpv_twitch_chat]       [C]: ?
[mpv_twitch_chat] Lua error: /home/maelstrom/.config/mpv/scripts/mpv-twitch-chat.lua:141: '=' expected near 'continue'

Distro details:

                                                                                                                        maelstrom@Legion 
    ⠀⠀⢀⣤⣴⣶⣶⣶⣦⣤⡀⠀⣀⣠⣤⣴⣶⣶⣶⣶⣶⣶⣶⣶⣤⣤⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀   ---------------- 
    ⠀⣰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣤⡀⠀⠀⠀⠀⠀⠀⠀⠀   OS: Nobara Linux 37 (KDE Plasma) x86_64 
    ⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣄⠀⠀⠀⠀⠀⠀   Host: 82B1 Lenovo Legion 5 15ARH05H 
    ⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣄⠀⠀⠀⠀   Kernel: 6.1.14-201.fsync.fc37.x86_64 
    ⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⠀⠀⠀   Uptime: 22 mins 
    ⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠋⠉⠁⠀⠀⠉⠉⠛⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⠀⠀   Packages: 2449 (rpm) 
    ⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠁⠀⠀⠀⢀⣀⣀⡀⠀⠀⠀⠈⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀   Shell: bash 5.2.15 
    ⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡏⠀⠀⠀⢠⣾⣿⣿⣿⣿⣷⡄⠀⠀⠀⠻⠿⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀   Resolution: 1920x1080 
    ⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠁⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⣀⣀⣬⣽⣿⣿⣿⣿⣿⣿⠀   DE: Plasma 5.27.2 
    ⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠈⠻⢿⣿⣿⡿⠟⠁⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀   WM: kwin 
    ⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀   Theme: [Plasma], Breeze [GTK2/3] 
    ⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣤⣤⣄⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀   Icons: [Plasma], breeze-dark [GTK2/3] 
    ⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣄⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀   Terminal: konsole 
    ⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣇⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀   CPU: AMD Ryzen 7 4800H with Radeon Graphics (16) @ 2.900GHz 
    ⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠟⠛⠉⠉⠛⠛⢿⣿⣿⠀⠀⠀⠀⠀⠸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠀   GPU: NVIDIA GeForce RTX 2060 Mobile 
    ⠀⠘⢿⣿⣿⣿⣿⣿⣿⣿⡿⠋⠀⠀⠀⠀⠀⠀⠀⠀⠈⢿⠀⠀⠀⠀⠀⠀⠙⢿⣿⣿⣿⣿⣿⣿⣿⠟⠁⠀   Memory: 3709MiB / 15862MiB 
    ⠀⠀⠀⠈⠙⠛⠛⠛⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⠛⠛⠛⠉⠁⠀⠀⠀
                                                                       
                                                                    

mpv version:

mpv 0.35.0 Copyright © 2000-2022 mpv/MPlayer/mplayer2 projects
 built on UNKNOWN
FFmpeg library versions:
   libavutil       57.28.100
   libavcodec      59.37.100
   libavformat     59.27.100
   libswscale      6.7.100
   libavfilter     8.44.100
   libswresample   4.7.100
FFmpeg version: 5.1.2

scipt-opts: error converting value 'false' for key 'ignore_sub'

The script is working fine but it's throwing errors for the script-opts file.

[mpv_twitch_chat] Error: Can't convert 'true' to boolean!

[mpv_twitch_chat] script-opts/mpv_twitch_chat.conf:1 error converting value 'true' for key 'show_name'

[mpv_twitch_chat] Error: Can't convert 'true' to boolean!

[mpv_twitch_chat] script-opts/mpv_twitch_chat.conf:2 error converting value 'true' for key 'color'

[mpv_twitch_chat] Error: Can't convert 'false' to boolean!

[mpv_twitch_chat] script-opts/mpv_twitch_chat.conf:3 error converting value 'false' for key 'ignore_sub'

live chat support

awesome plugin, thank you!
any plans on adding a live chat (irc) support?

rechat subtitle tracks missing in Twitch VODs.

Windows 10.
curl 7.55.1 (Windows) libcurl/7.55.1 WinSSL
mpv 0.33.0-228-g1e90ec647c
FFmpeg library versions:
libavutil 57.0.100
libavcodec 59.3.101
libavformat 59.4.100
libswscale 6.0.100
libavfilter 8.0.103
libswresample 4.0.100
FFmpeg version: git-2021-07-18-694545b6

Twitch VODs don't load any rechat subtitle tracks so mpv-twitch-chat doesn't work.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.