Giter VIP home page Giter VIP logo

media-source-extract's Introduction

无差别视频提取工具

  • 检测到符合条件的视频资源,自动注入代码。
  • 之后再也不需要自己注入代码啦,降低使用成本。
  • 可能有 Bug,但可以试试。如果使用中有问题,在 github 中提 issues 给我呗。 我们一起完善它。
  • 插件源码: https://github.com/Momo707577045/media-source-extract/blob/master/media-source-extract.user.js
  • 如果没成功检测到,咱们就用回老方法试试。再给我提个 bug。
  • 手动添加油猴插件步骤
    • 点击 tamper-monkey「油猴」icon,点击「添加新脚本」

    • 在当前位置,粘贴上述链接中的源码

    • 点击「文本」,「保存」

    • 得到如下结果,即为添加成功

背景

  • 之前笔者实现了m3u8 视频在线提取工具,可对 m3u8 视频进行提取,合并,下载。实现整个视频下载流程。

  • 后续还实现了非定制性的 ASE 解密功能(不提供定制性服务,定制性解密,属于破解,侵权行为,需尊重知识产权)

  • 但上述工具仍存在一定的通用性问题。为彻底解决通用性,实现无差别视频提取,开发了这个工具。

特点

  • 优点,通用性强,无差别提取,只要使用到 MES 主流媒体播放技术的视频,均可捕获。

  • 优点,足够简单,在视频播放的最后一个步骤进行拦截,规避视频加载,加密,解密等复杂过程。

  • 缺点,被动,无法主动干预视频加载,只可被动捕获视频资源。

  • 缺点,有一定门槛,依赖 chrome 浏览器开发者模式,无法实现全自动化,有一定使用门槛。

功能说明

  • 【已捕获 0 个片段】
    • 显示程序已捕获的视频片段数。
  • 【下载已捕获片段】
    • 可以强制下载已经捕获的片段,无需等待整个视频全部捕获完成。
  • 【十倍速捕获】
    • 由于视频捕获是依赖视频加载进度的。
    • 点击该按钮,可以十倍速播放,加速视频加载,加速视频捕获。
  • 当视频全部加载完成,将触发自动下载。
    • 若无触发,可手动点击「下载已捕获片段」按钮,对捕获到的视频进行下载。

使用方式

示例实验链接

  • 复制工具代码

    • 可以直接复制本文中的核心源码

    • 也可以点开示例实验链接,点击按钮,快速复制工具代码。

  • 打开目前页面的控制台

  • ctrl + f ,输入 <iframe,判断是否存在 iframe 内嵌页面。若存在 iframe,请看完本说明,再继续查看下一节「iframe 解决方案」。若无,则下一步

  • 打开代码调试面板

  • 在调试面板中,找到当前页面的代码

    • 注意文件的寻找方法,需根据 URL 中的路径层级寻找。
    • 点击下方按钮,对代码进行排版。

  • 搜索,找到第一个 <script 标签,并设置多个断点

    • 搜索,如果第一个 <script 标签是一个链接。

    • 则找到对应文件,设置断点。

  • 刷新页面,出现如下状态,则证明断点设置成功

    • 若页面白屏,为正常现象,按照步骤继续执行即可。
  • 在 console 栏,粘贴工具代码,回车

  • 回到 source 栏,点击按钮,恢复运行

  • 若页面出现这几个按钮,则证明注入成功,工具运行成功

  • 正常观看视频,等待视频捕获

    • 可点击「十倍速捕获」,接口视频播放速度,加快视频捕获速度。
  • 若页面出现如下弹窗,即捕获完成,视频自动下载(也可以点击「下载已捕获片段」,手动下载)

  • 视频下载完成,得到「音频」文件,「视频」文件

    • 可使用专属播放器,进行播放。

    • 也可以使用其他工具,进行合并。

iframe 解决方案

示例实验链接

  • 找到 iframe 标签,复制 src 中的 url,新建页面打开该 url。

    • 如果该新建页面能正常播放视频,则在该新建页面,使用上述「使用说明」即可。

  • 如果新建页面没有正常播放页面,则回到原页面,换一种方式实现。

  • 回到原页面,找到 iframe 内嵌页面的源码。

    • 同样搜索 <script,但这一次,要找带 src 的 script 标签

  • 找到该 src 对应的文件,并打断点

  • 刷新页面,并在源文件中,插入代码

    • 注意,打断点和插入代码是在不同的栏,打断点的栏中,有「:format」标识。插入代码的栏,没有该标识。

  • 粘贴代码,ctrl + s 进行保存

  • 恢复执行(操作方式,查看上一节「使用说明」)

  • 完成代码插入,捕获视频

特别说明

  • 在代码操作过程中,页面白屏是正常的,按照步骤继续执行即可。

  • 如果不行,安装使用说明,多试几遍就可以了。可能是视频广告导致。

  • 注意 Chrome 的多文件下载询问,如果拒绝过,需要重新打开。

  • 视频捕获,分为「视频」文件与「音频」文件,「视频」文件是纯视频,没声音的。需要搭配「音频」文件播放。点击这里,使用专属播放器。

  • 由于采集工具是单独对「视频」和「音频」分开采集的。

  • 使用普通播放器可能无法正常播放。

  • 可利用本工具同时加载「视频」和「音频」同步播放。

  • 本工具还附有倍速播放功能。

window 系统,音视频合成方法

  • 可使用「小丸工具箱」完成
  • 具体的方式,笔者没有实践过,有经验的朋友欢迎在评论区留言使用教程。万分感谢。
  • 特别感谢㍿⃣ 介绍的「小丸工具箱」解决方案

mac 系统,音视频合成方法

  • 安装 ffmpeg 视频编辑库

  • 先把音频「audio_mp4」进行转码

    • 命令行执行 ffmpeg -i "***-audio_mp4;codecs=***.mp4" -acodec copy "audio.aac"
  • 原始视频「video_mp4」和上一步得到的 aac 「audio.aac」组装到一起

    • 命令行执行 ffmpeg -i "***-video_mp4;codecs=***.mp4" -i "audio.aac" -c copy -shortest "result.mp4"
  • 得到的「result.mp4」就是音视频合成成功的视频

  • 特别感谢journey-ad 介绍的 ffmpeg 合成教程。

原理

  • 主流视频媒体播放技术,均使用到 MES 技术

  • MES 技术播放流程一般如下:

    • 创建 video 播放器标签。

    • 拉取视频片段。

    • 解密视频片段(如果对视频进行了加密操作)

    • 解析视频片段,分为「视频轨」「音频轨」。

    • 将每个片段的「视频轨」「音频轨」,"喂给" video 标签进行播放。

    • 当已加载的视频片段快要播完时,重复第二个步骤,拉取新的视频片段,进行投喂。

  • 本工具的核心逻辑

    • 覆写视频片段的"投喂"操作。
    • 插入自定义代码,收集"投喂"的「视频」「音频」资源,进行下载。

核心源码(共 91 行)

(function () {

  let _sourceBufferList = []
  let $btnDownload = document.createElement('div')
  let $downloadNum = document.createElement('div')
  let $tenRate = document.createElement('div') // 十倍速播放

  // 十倍速播放
  function _tenRatePlay () {
    let $domList = document.getElementsByTagName('video')
    for (let i = 0, length = $domList.length; i < length; i++) {
      const $dom = $domList[i]
      $dom.playbackRate = 10
    }
  }

  // 下载捕获到的资源
  function _download () {
    _sourceBufferList.forEach((target) => {
      const mime = target.mime.split(';')[0]
      const type = mime.split('/')[1]
      const fileBlob = new Blob(target.bufferList, { type: mime }) // 创建一个Blob对象,并设置文件的 MIME 类型
      const a = document.createElement('a')
      a.download = `${document.title}.${type}`
      a.href = URL.createObjectURL(fileBlob)
      a.style.display = 'none'
      document.body.appendChild(a)
      a.click()
      a.remove()
    })
  }

  // 监听资源全部录取成功
  let _endOfStream = window.MediaSource.prototype.endOfStream
  window.MediaSource.prototype.endOfStream = function () {
    alert('资源全部捕获成功,即将下载!')
    _download()
    _endOfStream.call(this)
  }

  // 捕获资源
  let _addSourceBuffer = window.MediaSource.prototype.addSourceBuffer
  window.MediaSource.prototype.addSourceBuffer = function (mime) {
    console.log(mime)
    let sourceBuffer = _addSourceBuffer.call(this, mime)
    let _append = sourceBuffer.appendBuffer
    let bufferList = []
    _sourceBufferList.push({
      mime,
      bufferList,
    })
    sourceBuffer.appendBuffer = function (buffer) {
      $downloadNum.innerHTML = `已捕获 ${_sourceBufferList[0].bufferList.length} 个片段`
      bufferList.push(buffer)
      _append.call(this, buffer)
    }
    return sourceBuffer
  }

  // 添加操作的 dom
  function _appendDom () {
    const baseStyle = `
      position: fixed;
      top: 50px;
      right: 50px;
      height: 40px;
      padding: 0 20px;
      z-index: 9999;
      color: white;
      cursor: pointer;
      font-size: 16px;
      font-weight: bold;
      line-height: 40px;
      text-align: center;
      border-radius: 4px;
      background-color: #3498db;
      box-shadow: 0 3px 6px 0 rgba(0, 0, 0, 0.3);
    `
    $tenRate.innerHTML = '十倍速捕获'
    $downloadNum.innerHTML = '已捕获 0 个片段'
    $btnDownload.innerHTML = '下载已捕获片段'
    $tenRate.style = baseStyle + `top: 150px;`
    $btnDownload.style = baseStyle + `top: 100px;`
    $downloadNum.style = baseStyle
    $btnDownload.addEventListener('click', _download)
    $tenRate.addEventListener('click', _tenRatePlay)
    document.getElementsByTagName('html')[0].insertBefore($tenRate, document.getElementsByTagName('head')[0]);
    document.getElementsByTagName('html')[0].insertBefore($downloadNum, document.getElementsByTagName('head')[0]);
    document.getElementsByTagName('html')[0].insertBefore($btnDownload, document.getElementsByTagName('head')[0]);
  }

  _appendDom()
})()

声明

  • 本项目仅用于学习,交流,切勿用于侵权行为。

media-source-extract's People

Contributors

le0zh0u avatar momo707577045 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  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

media-source-extract's Issues

大佬哥哥,怎么下载和家亲的视频啊

我想下载和家亲监控的视频。也就是回放之类的。
但是抓不到M3U8文件。请问怎么解决啊,下载......
video.komect.com/ydkj

因为要登录的,如果您有办法的可以方便加个联系方式吗。

Title:单次可下载短视频数量问题

您好,我使用此插件下载学校提供的网课,因为网课资源都是几分钟一个知识点一小段例题的讲解,我注销掉代码中资源自动捕获下载的{//监听资源全部录取成功}一段代码后,每次播放5个之内的视频片段都可以正常下载0~9十个文件,但当单次点击播放超过5个小视频时虽然显示捕获的片段计数在增加,点击下载已捕获片段时却还是0~9这前5个视频的文件,请问待下载的文件列表长度如何修改,谢谢!

image

Windows下合并音视频脚本

使用方法就是下载每次不都是xxx.mp4和xxx (1).mp4,把2个文件丢一起然后bat和ffmpeg.exe丢一起,xxx.mp4丢bat上就行了
下面内容保存为bat

@echo off
REM 读取第一个参数
SET param=%1
REM 不论param有没有双引号,都给其加上
SET param="%param%"
REM 将param中的所有双引号删除
SET param=%param:"=%
REM 给没有双引号的param加上双引号
rem SET param="%param%"

set filename=%param%
set filename=%filename:~0,-4%
set audio_file="%filename%.mp4"
set aac_file="%filename%.aac"
set video_file="%filename% (1).mp4"
set result_file="%filename%_merged.mp4"
echo %filename%
echo %audio_file%
echo %aac_file%
echo %video_file%

echo 1.export aac audio
rem 先把音频分离出来
rem ffmpeg -i "audio.m4a" -acodec copy "tmp_audio.aac"
ffmpeg -i %audio_file% -acodec copy %aac_file%
echo 2.merge aac and video
rem 然后把原始视频和上一步得到的aac组装到一起
rem ffmpeg -i "video.mp4" -i "tmp_audio.aac" -c copy -shortest "output.mp4"
ffmpeg -i %video_file% -i %aac_file% -c copy -shortest %result_file%
echo finish
pause

https://github.com/nilaoda/N_m3u8DL-CLI/releases/download/3.0.2/N_m3u8DL-CLI_v3.0.2_with_ffmpeg_and_SimpleG.zip
这里面有带个ffmpeg.exe我试了下可用

20220320 Mac pro播放下载下来的mp4出现电火花问题

20220320我通过暴力猴结合media-source-extract脚本下载了一段 spotify网页音频,使用Mac pro本地 INNA 播放器播放,结果电脑出现电火花,等待维修中,不敢继续用这个media-source-extract 脚本了。同时,下载下来的spotify网页音频无法正常播放,电脑,手机都不能正常播放。

建议输出为原格式

大佬

有些网站会用到多个m3u8同时播放。例如纯视频用一个m3u8,纯音频用另一个m3u8,然后两个同时播放。
这个插件在缓存合并的时候,会自动把ts文件合并成mp4,这样音频就会出一些问题(不知道是格式转换的问题还是我电脑的问题...)
建议直接输出为原格式ts,不自动转换为mp4说不定能解决音频乱码 :) 😁

音视频合并已解决(手工,非代码)

首先,非常感谢作者!
音频合并不了。是因为时间戳DTS不对。要么从原网站扒SourceBuffer的js。下载时间戳,然后和下载的音频核对。视频也需要核对时间戳。这种方法可以保证和原视频一模一样。
另一种方法。基于视频重新生成时间戳。这种方法视频的时间可能和原来快或慢个几秒,不过无关紧要。会c++可以调用c++ 视频库处理。不会可以用工具。具体做法:
1.用mkvtoolnix把音频和视频封装成mkv
2.demux出基于视频生成的m4v(音频,这个音频的时间戳是基于视频的)
3在把m4v和原来的视频封装成mkv。
4用Handbrake转码成mp4。
前面的过程不要用ffmpeg!!!!
5最后用ffmpeg再处理一下mp4(转码)
最后放上我转码合并过的mp4:
https://wwa.lanzous.com/iZLzNkgxp1a

Amazon Prime Video 无效

Prime Video是在页面上点击后直接弹出播放器播放而没有打开新页面,开始播放后并未显示捕获等按钮。

下载音频格式,ffmpeg合并后可以正常使用

建议:下载资源时或许可以检测mime开头是audio,则将后缀设置成mp3或其他
ffmepg合并命令:
ffmpeg -i "${videoPath}" -i "${audioPath}" -vcodec copy "${outputName}"
经测试音频正常,无损合并

Buffering videos

Hello, thank you so much for thiese awesome amazing scripts and tools 🥇 !!

please I have a wish which is very useful for many poeple, sometimes the internet connection is weak and it is necessary to buffer full video or increase the size of the video buffering to avoid jerky interruptions on streaming sites and for smooth playback, I found how buffer full video and even buffer youtube videos with firefox browser by putting:

cache_readahead_limit: 999999
cache_resume_threshold: 999999

set media.mediasource.enabled to false

I even made a personal discovery and I discovered that when I deactivate the different types of cache:

set browser.cache.disk.enable, browser.cache.disk.smart_size.enabled, browser.cache.disk_cache_ssl and browser.cache.offline.enable to false

I can buffer full streaming video!!!

but on chrome and chromium, it's more complicated because chrome removed MSE media source extension API from chrome flags....

I tried several things: enable command line and chrome flags to increase buffering in chrome chromium:

--video-underflow-threshold-ms

chrome flag: Increase the nesting threshold before which setTimeout(..., <4ms) start being clamped.

--mse-audio-buffer-size-limit-mb

--mse-video-buffer-size-limit-mb

--enable-protected-video-buffers

--audio-buffer-size --force-protected-video-output-buffers

-enable-swap-buffers-with-bounds

--mem-pressure-system-reserved-kb

--aggressive-cache-discard -disable-back-forward-cache

--enable-protected-video-buffers --mse-video-buffer-size-limit-mb=150 --mse-audio-buffer-size-limit-mb=10

I even installed different scripts for full buffering and even used the console in developer mode:

youtube buffer enhence

https://greasyfork.org/en/scripts/442685-youtube-buffer-enhence-%E7%BC%93%E5%86%B2%E5%A2%9E%E5%8A%A0

GREASYFORK USESCRIPTS Custom Native HTML5 Player with Shortcuts

Force a full preload HTML5 video with Javascript?
https://stackoverflow.com/questions/16581801/force-a-full-preload-html5-video-with-javascript

HTML5 video full preload in javascript

https://stackoverflow.com/questions/9616236/html5-video-full-preload-in-javascript/23299806#23299806

jQuery.html5Loader
https://github.com/GianlucaGuarini/jquery.html5loader

MSE Dump Tools
Media Source Extensions API 数据 Dump 工具

https://greasyfork.org/en/scripts/420325-mse-dump-tools

Custom Native HTML5 Player with Shortcuts
https://greasyfork.org/en/scripts/404717-custom-native-html5-player-with-shortcuts

YouTube - Auto-Buffer & Auto-HD

krisnoble
/
mediabuffer

Buffer HTML5 audio/video for uninterrupted playback.

https://github.com/krisnoble/Mediabuffer
Youtube Pause and full buffer

PONY56

https://pastebin.com/ZGcpri47

What it does:
It pauses your youtube video. When video stop buffering it manually move the seeker to force the download.
When the download is finished, it places the cursor back to it's original position. You are then ready to play a fully buffered video.
*/

/*
How to use:
Paste this script in the console of your browser (F12 > Console). Tested on Firefox Linux.
*/

// Note: Maximize your "browser.cache.disk.capacity" (type "about:config" in Firefox) if you are loading long videos......

I tried all that but failed to enable buffer full video, I tried disabling cache in developer console, and put:

--disk-cache-size=2147483647

--disk-cache-size=1 --media-cache-size=1

but it didn't work, we will be grateful if you have the generosity to find a way or make a script to increase the video buffering or buffer fill video especially when watching full HD video with a weak internet connection which becomes a nightmare, thank you very much !!

视频的mp4无法使用ffmpeg合成

大佬,我下载好之后,拿到两个MP4文件,一个视频,一个音频。音频的可以提取出声音。之后和视频进行混合时就出现错误了,使用ffmpeg,格式工厂,小丸工具箱都不行。错误提示都是:
[mov,mp4,m4a,3gp,3g2,mj2 @ 0000026b88109640] error reading header
D:/file/video.mp4: Invalid data found when processing input
Error file name :video.mp4
好像是MP4视频文件信息的问题。我在小丸工具箱中看到视频MP4文件的id是0,正常可播放的id都是1开始的。有关这一点,麻烦大佬可以查一下是什么问题嘛?

遇到两个问题

使用平台: Chrome 105.0.5195.125, 油猴 v4.16.1, 脚本版本 0.6. 遇到以下两个问题:

  1. 昨晚开始, 小鹅通的视频在捕捉完或点击下载已捕获片段后会弹出一个 blob: 开头的网页, 似乎是一个渲染失败的视频, 无法下载, 如图所示:
    截屏

  2. 在网站 https://www.luffycity.com/ 启用脚本时会提示 “视频禁止在小窗口播放”.
    截屏2

视频时差限制为4分钟

你好,插件惊为天人
最近遇到一个问题,现在的视频时差极限在4分钟,超出4分钟的部分,无法下载,怎么解决呢

播放完自动退出

倍速播放完毕,抓捕所有分段后还没下载就退出了(返回到播放列表)

网页端视频没有声音了

下了视频文件后网页端的视频就没有声音了!!!!!! 下载下来的没有音频 原先网页端好端端的视频也变成无声的了!!!!

推荐个macos可以使用的自动合并音视频脚本

还是先安装brew和ffmpeg,然后把视频和音频放置在和脚本同一个目录,并且新建一个文件夹命名为finish,之后在命令行运行如下脚本即可,自动合并当前目录下同名的所有的音频和视频,规则是把小的文件作为音频,大的作为视频,且只查询*.mp4和* (1).mp4的文件,合并后的源文件会移动到finish中,当前目录下剩余的就是转换后的。
###################
OLD_IFS=$IFS
IFS='
'
for file in $(ls *.mp4)
do
file_tmp=${file// (1).mp4/}
file_tmp=${file_tmp//.mp4/}
if [ -a "${file_tmp}.mp4" ] && [ -a "${file_tmp} (1).mp4" ]; then
size_1=ls -l "${file_tmp}.mp4" | awk '{ print $5 }'
size_2=ls -l "${file_tmp} (1).mp4" | awk '{ print $5 }'
if [ $size_1 > $size_2 ]; then
ffmpeg -i "${file_tmp} (1).mp4" -acodec copy "${file_tmp}.aac"
ffmpeg -i "${file_tmp}.mp4" -i "${file_tmp}.aac" -c copy -shortest "${file_tmp}_result.mp4"
fi
if [ $size_1 < $size_2 ]; then
ffmpeg -i "${file_tmp}.mp4" -acodec copy "${file_tmp}.aac"
ffmpeg -i "${file_tmp} (1).mp4" -i "${file_tmp}.aac" -c copy -shortest "${file_tmp}_result.mp4"
fi
mv "${file_tmp}.mp4" finish/
mv "${file_tmp} (1).mp4" finish/
rm *.aac
fi
done
IFS=$OLD_IFS
################
拷贝上述代码到一个shell脚本,如test.sh,之后命令行执行sh test.sh即可。

非常棒的脚本!我自己稍微改动了一下,可以不自动下载,而是让使用者自行选择是否下载。本人菜菜鸟,如有不当请海涵

//稍微改动了一下以下的地方

// 监听资源全部录取成功
let _endOfStream = window.MediaSource.prototype.endOfStream
window.MediaSource.prototype.endOfStream = function() {
  if (!isClose) {
    //alert('资源全部捕获成功,即将下载!')
      let isDownLoadNow = confirm("资源全部捕获成功,共"+_sourceBufferList.length+"个。现在下载吗?")
      if(isDownLoadNow){
          _download()
          _endOfStream.call(this)
      }
  }
}

視頻自動下載建議去掉

這個插件正常使用時會自動捕獲視頻,當全部片段捕獲完畢時會強制下載,不能取消,但是很多時候這是不需要的,尤其是有時會捕獲廣告,然後被迫下載一堆非目標的視頻。

建議,可以將啟用時機設為 右鍵選單啟用,這樣可以按需啟用這個插件(在代碼中標記 // @run-at context-menu)不然用戶安裝時多數都不懂去油猴調整選項,發布的腳本那個設定頁面的是不會帶進去的。

或是把自動下載那裡的alert改為confirm,給用戶提供一個取消的選項。

我現在使用的是我自行修改過得,把_download()給註釋掉了

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.