Giter Club home page Giter Club logo

ranman / amazon-kinesis-video-streams-producer-sdk-cpp Goto Github PK

View Code? Open in Web Editor NEW

This project forked from awslabs/amazon-kinesis-video-streams-producer-sdk-cpp

1.0 1.0 1.0 730 KB

Amazon Kinesis Video Streams Producer SDK for C++ is for developers to install and customize for their connected camera and other devices to securely stream video, audio, and time-encoded data to Kinesis Video Streams.

License: Other

Shell 1.66% C++ 86.04% CMake 1.47% C 10.83%

amazon-kinesis-video-streams-producer-sdk-cpp's Introduction

Amazon Kinesis Video Streams Producer SDK C/C++

License

This library is licensed under the Amazon Software License.

Introduction

Amazon Kinesis Video Streams makes it easy to securely stream video from connected devices to AWS for analytics, machine learning (ML), and other processing.

Amazon Kinesis Video Streams Producer SDK for C/C++ makes it easy to build an on-device application that securely connects to a video stream, and reliably publishes video and other media data to Kinesis Video Streams. It takes care of all the underlying tasks required to package the frames and fragments generated by the device's media pipeline. The SDK also handles stream creation, token rotation for secure and uninterrupted streaming, processing acknowledgements returned by Kinesis Video Streams, and other tasks.

Kinesis Video Streams Producer SDK for C/C++

Amazon Kinesis Video Streams Producer SDK for C/C++ contains the following sub-directories/projects:

  • kinesis-video-pic - The Platform Independent Codebase which is the basic building block for the C++/Java producer SDK. The project includes multiple sub-projects for each sub-component with unit tests.
  • kinesis-video-producer - The C++ Producer SDK with unit test.
  • kinesis-video-producer-jni - The C++ wrapper for JNI to expose the functionality to Java/Android.
  • kinesis-video-gst-demo - C++ GStreamer sample application (for webcam, USB camera and RTSP) .
  • kinesis-video-gstreamer-plugin - GStreamer plugin sink element (kvssink) and demo application.
  • kinesis-video-native-build - Native build directory with a build script for Mac OS/Linux/Raspberry PI. This is the directory that will contain the artifacts (executable binaries) and JNI libraries after the build.

How to build Producer SDK and sample applications

There are few build-time tools/dependencies which need to be installed in order to build the core producer SDK libraries and the sample applications. The open source dependencies can be built either by building them from source or using package installers (like brew/apt-get).

Pre-requisites:

In order to build the Producer SDK and download open source dependencies the following are required. One option is to use brew install (in Mac OS X) or apt-get install (in Linux) to install the following build tool dependencies.

1. Build tools

  • cmake 3.7/3.8 https://cmake.org/
  • autoconf 2.69 (License GPLv3+/Autoconf: GNU GPL version 3 or later) http://www.gnu.org/software/autoconf/autoconf.html
  • flex 2.5.35 Apple(flex-31)
  • bison 2.4 (GNU License)
  • automake 1.15.1 (GNU License)
  • libtool (Apple Inc. version cctools-898)
  • xCode (Mac OS) / clang / gcc (xcode-select version 2347)
  • Java JDK (if Java JNI compilation is required)

2. Certificate store integration (not required for releases > 1.4.1)

Kinesis Video Streams Producer SDK for C++ needs to establish trust with the backend service through TLS. This is done through validating the CAs in the public certificate store. On Linux-based models, this store is located in /etc/ssl/ directory by default.

Please download the PEM file from https://www.amazontrust.com/repository/SFSRootCAG2.pem

to /etc/ssl/cert.pem. Append to the end of the file if it exists by running sudo cat SFSRootCAG2.pem >> /etc/ssl/cert.pem.

Many platforms come with a cert file with a lot of the well-known public certs in them.

3.A Build the SDK and sample applications using open source dependencies built from source

The install-script will download and build the dependent open source components into the 'downloads' directory within kinesis-video-native-build directory (<producer-sdk-dir>/kinesis-video-native-build/downloads) and link against it.

After you've downloaded the code from GitHub, you can build it on Mac OS or Ubuntu by running ./install-script (which is inside the kinesis-video-native-build directory).

Important Change current working directory to the kinesis-video-native-build directory first. Then run the ./install-script from that directory.

This will produce the core library, unit tests executable and the sample GStreamer application. The install-script will take some time to bring down and compile the open source components depending on the network connection and processor speed. If anything fails or the script is interrupted, re-running it will pick up from the place where it last left off. The sub-sequent run will be building just the modified SDK components or applications which is much faster.

3.B Build the SDK and sample applications using system versions of open source library dependencies

The bulk of the install script is building the open source dependencies. The project is based on CMake. So the open source components building can be skipped if the system versions can be used for linking.

Running

$ cmake .
$ make

from the kinesis-video-native-build directory will build and link the SDK.

The ./min-install-script inside the kinesis-video-native-build captures these steps for installing the Kinesis Video Streams Producer SDK with the system versions for linking.

4 Build the Producer SDK as a GStreamer plugin (sink) element.

You can build it on Mac OS or Ubuntu by running ./gstreamer-plugin-install-script (which is inside the kinesis-video-native-build directory).

5. Build the native library (KinesisVideoProducerJNI) to run Java Demo App

The ./java-install-script inside kinesis-video-native-build will build the KinesisVideoProducerJNI native library to be used by Java Producer SDK.


The following section provides guidance for installing the open source dependencies using apt-get in Linux. Similar approach can be followed for installing in Mac-OS using brew.

Install Steps for Ubuntu 17.x using apt-get

The following are the steps to install the build-time prerequisites for Ubuntu 17.x

Install git:

$ sudo apt-get install git
$ git --version
git version 2.14.1

Install cmake:

$ sudo apt-get install cmake
$ cmake --version
cmake version 3.9.1

CMake suite maintained and supported by Kitware (kitware.com/cmake).

Install libtool: (some images come preinstalled) amd libtool-bin

$ sudo apt-get install libtool
$ sudo apt-get install libtool-bin
$ libtool --version
libtool (GNU libtool) 2.4.6
Written by Gordon Matzigkeit, 1996

Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Install automake:

$ sudo apt-get install automake
$ automake --version
automake (GNU automake) 1.15
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl-2.0.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Tom Tromey <[email protected]>
       and Alexandre Duret-Lutz <[email protected]>.

Install g++:

$ sudo apt-get install g++
$ g++ --version
g++ (Ubuntu 7.2.0-8ubuntu3) 7.2.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Install curl:

$ sudo apt-get install curl
$ curl --version
curl 7.55.1 (x86_64-pc-linux-gnu) libcurl/7.55.1 OpenSSL/1.0.2g zlib/1.2.11 libidn2/2.0.2 libpsl/0.18.0 (+libidn2/2.0.2) librtmp/2.3
Release-Date: 2017-08-14
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp smb smbs smtp smtps telnet tftp
Features: AsynchDNS IDN IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz TLS-SRP UnixSockets HTTPS-proxy PSL

Install pkg-config:

$ sudo apt-get install pkg-config
$ pkg-config --version
0.29.1

Install flex:

$ sudo apt-get install flex
$ flex --version
flex 2.6.1

Install bison:

$ sudo apt-get install bison
$ bison -V
bison (GNU Bison) 3.0.4
Written by Robert Corbett and Richard Stallman.

Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Install Open JDK:

$ sudo apt-get install openjdk-8-jdk
$ java -showversion
openjdk version "1.8.0_151"
OpenJDK Runtime Environment (build 1.8.0_151-8u151-b12-0ubuntu0.17.10.2-b12)
OpenJDK 64-Bit Server VM (build 25.151-b12, mixed mode)

Set JAVA_HOME environment variable:

$ export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/

Run the build script: (within kinesis-video-native-build folder)

./install-script

Examples

Sample demo applications for sending video to Kinesis Video Streams.

Setting credentials in environment variables

Define AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables with the AWS access key id and secret key:

$ export AWS_ACCESS_KEY_ID=YourAccessKeyId
$ export AWS_SECRET_ACCESS_KEY=YourSecretAccessKey

optionally, set AWS_SESSION_TOKEN if integrating with temporary token and AWS_DEFAULT_REGION for the region other than us-west-2

Setting the LD_LIBRARY_PATH

Export the LD_LIBRARY_PATH=<full path to your sdk cpp directory>/kinesis-video-native-build/downloads/local/lib. For example, if you have downloaded the CPP SDK in /opt/awssdk directory then you can set the LD_LIBRARY_PATH as below:

export LD_LIBRARY_PATH=/opt/awssdk/amazon-kinesis-video-streams-producer-sdk-cpp/kinesis-video-native-build/downloads/local/lib:$LD_LIBRARY_PATH
1. GStreamer webcam demo application

The demo application kinesis_video_gstreamer_sample_app in the kinesis-video-native-build directory uses GStreamer pipeline to get video data from the camera. Launch it with a stream name and it will start streaming from the camera. The user can also supply a streaming resolution (width and height) through command line arguments.

Usage: AWS_ACCESS_KEY_ID=YourAccessKeyId AWS_SECRET_ACCESS_KEY=YourSecretAccessKey ./kinesis_video_gstreamer_sample_app -w <width> -h <height> -f <framerate> -b <bitrateInKBPS> <my_stream_name>
  • A. If resolution is provided then the sample will try to check if the camera supports that resolution. If it does detect that the camera can support the resolution supplied in command line, then streaming starts; else, it will fail with an error message Resolution not supported.
  • B. If no resolution is specified, the demo will try to use these three resolutions 640x480, 1280x720 and 1920x1080 and will start streaming once the camera supported resolution is detected.
2. GStreamer RTSP demo application

The GStreamer RTSP demo app will be built in kinesis_video_gstreamer_sample_rtsp_app in the kinesis-video-native-build directory. Launch it with a stream name and rtsp_url and it will start streaming.

AWS_ACCESS_KEY_ID=YourAccessKeyId AWS_SECRET_ACCESS_KEY=YourSecretAccessKey ./kinesis_video_gstreamer_sample_rtsp_app <my_rtsp_url> my-rtsp-stream
3. Running the GStreamer plugin from gst-launch-1.0

The gst-launch-1.0 and gst-inspect-1.0 binaries are built inside the folder <YourSdkFolderPath>/kinesis-video-native-build/downloads/local/bin. You can either run the following commands from that folder using ./gst-launch-1.0 or you can include that in your path environment variable using the following export command and run gst-launch-1.0

$ export PATH=<YourSdkFolderPath>/kinesis-video-native-build/downloads/local/bin:$PATH

Set the path for the producer SDK plugin so that GStreamer can locate it.

$ export GST_PLUGIN_PATH=<YourSdkFolderPath>/kinesis-video-native-build/downloads/local/lib:$GST_PLUGIN_PATH
3.1 Run the following gst-launch-1.0 command to start streaming from RTSP camera source.
$ gst-launch-1.0 rtspsrc location=rtsp://YourCameraRtspUrl short-header=TRUE ! rtph264depay ! video/x-h264, format=avc,alignment=au ! kvssink stream-name=YourStreamName storage-size=512
3.2 Run the following gst-launch-1.0 command to start streaming from USB camera source in Ubuntu.
$ gst-launch-1.0 v4l2src do-timestamp=TRUE device=/dev/video0 ! videoconvert ! video/x-raw,format=I420,width=640,height=480,framerate=30/1 ! x264enc  bframes=0 key-int-max=45 bitrate=500 ! video/x-h264,stream-format=avc,alignment=au ! kvssink stream-name=YourStreamName storage-size=512
3.3 Run the following gst-launch-1.0 command to start streaming from USB camera source which has h264 encoded stream already in Ubuntu.
$ gst-launch-1.0 v4l2src do-timestamp=TRUE device=/dev/video0 ! h264parse ! video/x-h264,stream-format=avc,alignment=au ! kvssink stream-name=YourStreamName storage-size=512
3.4 Run the following gst-launch-1.0 command to start streaming from camera source in Mac-OS.
$ gst-launch-1.0 autovideosrc ! videoconvert ! video/x-raw,format=I420,width=640,height=480,framerate=30/1 ! vtenc_h264_hw allow-frame-reordering=FALSE realtime=TRUE max-keyframe-interval=45 bitrate=500 ! h264parse ! video/x-h264,stream-format=avc,alignment=au,width=640,height=480,framerate=30/1 ! kvssink stream-name=YourStreamName storage-size=512
3.5 Run the following gst-launch-1.0 command to start streaming from camera source in Raspberry-PI.
$ gst-launch-1.0 v4l2src do-timestamp=TRUE device=/dev/video0 ! videoconvert ! video/x-raw,format=I420,width=640,height=480,framerate=30/1 ! omxh264enc control-rate=1 target-bitrate=5120000 periodicity-idr=45 inline-header=FALSE ! h264parse ! video/x-h264,stream-format=avc,alignment=au,width=640,height=480,framerate=30/1 ! kvssink stream-name=YourStreamName frame-timestamp=dts-only access-key=YourAccessKey secret-key=YourSecretKey

Note: Raspberry PI camera module requires frame-timestamp=dts-only . If USB camera is used for streaming then this property is optional.

4. Run the demo application from Docker

Refer the README.md file in the docker_native_scripts folder for running the build and RTSP demo application within Docker container.

Additional examples

For additional examples on using Kinesis Video Streams Java SDK and Kinesis Video Streams Parsing Library refer:


Running C++ Unit tests

The executable for unit tests will be built in ./start inside the kinesis-video-native-build directory. Launch it and it will run the unit test and kick off dummy frame streaming.

Enabling verbose logs

Define HEAP_DEBUG and LOG_STREAMING C-defines by uncommenting the appropriate lines in CMakeList.txt in the kinesis-video-native-build directory.


How to configure log for producer SDK sample applications.

For the sample demo applications included in the producer SDK (CPP), the log configuration is referred from the file kvs_log_configuration (within the kinesis-video-native-build folder).

Refer sample configuration in the folder kinesis-video-native-build for details on how to set the log level (DEBUG or INFO) and output options (whether to send log output to either console or file (or both)).

L1. Log output messages to console:

By default, the log configuration

log4cplus.rootLogger=DEBUG, KvsConsoleAppender

creates console appender (KvsConsoleAppender) which outputs the log messages in the console.

L2. Log output messages to file:

By adding file appender (KvsFileAppender) in the rootLogger of log4cplus as

log4cplus.rootLogger=DEBUG, KvsConsoleAppender, KvsFileAppender

the debug messages will be stored in kvs.log file in the sub-folder log within kinesis-video-native-build directory. The filename for the logs and the location can be modified by changing the line log4cplus.appender.KvsFileAppender.File=./log/kvs.log


Open Source Dependencies

The projects depend on the following open source components. Running install-script will download and build the necessary components automatically.

Producer SDK Core

Unit Tests

GStreamer Demo App

  • gstreamer - License
  • gst-plugins-base
  • gst-plugins-good
  • gst-plugins-bad
  • gst-plugins-ugly
  • x264

Troubleshooting

T.1. Ubuntu builds link issues

Ubuntu bulds link against the system versions of the open source component libraries or missing .so files (./start in the kinesis-video-native-build directory shows linkage against system versions of the open source libraries).We are working on providing fix but the immediate steps to remedy is to run

  rm -rf ./kinesis-video-native-build/CMakeCache.txt ./kinesis-video-native-build/CMakeFiles

and run

 ./install-script

to rebuild and re-link the project only.

T.2. Certificate issues during install-script build

If you see errors during the build as curl failed with 'unable to get local issuer certificate' then you can either follow the resolution steps in 81 or you can download the cacert.pem into the kinesis-video-native-build folder and run ./install-script -c.

T.3. Library not found error when running the demo application

If any error similar to the following shows that the library path is not properly set:

 liblog4cplus-1.2.so.5: cannot open shared object file: No such file or directory

To resolve this issue, export the LD_LIBRARY_PATH=<full path to your sdk cpp directory>/kinesis-video-native-build/downloads/local/lib. If you have downloaded the CPP SDK in /opt/awssdk directory then you can set the LD_LIBRARY_PATH as below:

export LD_LIBRARY_PATH=/opt/awssdk/amazon-kinesis-video-streams-producer-sdk-cpp/kinesis-video-native-build/downloads/local/lib:$LD_LIBRARY_PATH

T.4. Raspberry PI failure to load the camera device.

To check this is the case run ls /dev/video* - it should be file not found. The remedy is to run the following:

$ls /dev/video*
{not found}
$vcgencmd get_camera

Example output:

supported=1 detected=1

if the driver does not detect the camera then

  • Check for the camera setup and whether it's connected properly
  • Run firmware update $ sudo rpi-update and restart
$sudo modprobe bcm2835-v4l2
$ls /dev/video*
{lists the device}
T.5. Raspberry PI timestamp/range assertion at runtime.

Update the Raspberry PI firmware.

$ sudo rpi-update
$ sudo reboot
  • Raspberry PI GStreamer assertion on gst_value_set_fraction_range_full: assertion 'gst_util_fraction_compare (numerator_start, denominator_start, numerator_end, denominator_end) < 0' failed. The uv4l service running in the background. Kill the service and restart the sample app.
T.6. Raspberry PI seg faults after some time running on libx264.so.

Rebuilding the libx264.so library and re-linking the demo application fixes the issue.

T.6. Curl SSL issue - "unable to get local issuer certificate"

If curl throws "Peer certificate cannot be authenticated with given CA certificates: SSL certificate problem: unable to get local issuer certificate" error while sending data to KVS, then the local curl was not built properly with --with-ca-bundle path. So please remove the curl binaries and libraries and rebuilt it again by following below steps.

rm <producer_sdk_path/kinesis-video-native-build/downloads/local/lib/libcurl*
rm <producer_sdk_path/kinesis-video-native-build/downloads/local/bin/curl*
cd <producer_sdk_path/kinesis-video-native-build/downloads/curl-7.57.0
export DOWNLOADS=<producer_sdk_path>/kinesis-video-native-build/downloads
make clean
./configure --prefix=$DOWNLOADS/local/ --enable-dynamic --disable-rtsp --disable-ldap --without-zlib --with-ssl=$DOWNLOADS/local/ --with-ca-bundle=/etc/ssl/cert.pem
make
make install

Release notes

Release 1.4.3 (20th June 2018)

  • Added prebuilt docker images for AmazonLinux and Raspbian Stretch
  • Updated install-script to accept commandline argument -j and pass the value to make to speed up building
  • Updated install-script to accept commandline argument -d to remove opensource library installation files after finishing
  • Updated CMakeLists.txt in kinesis-video-native-build to link up libraries properly

Release 1.4.2 (14th June 2018)

  • Release first version of gstreamer plugin kvssink
  • Fix gstreamer demo issue when running on raspberry pi

Release 1.4.1 (8th May 2018)

  • Update log4cplus download link in install-script

Release 1.4.0 (25th April 2018)

  • Fix for crash caused by latest Mac tool chain issue
  • Fix for callbacks returning incorrect custom data in gstreamer sample app
  • Support for custom logger
  • Fix for multiple callbacks when triggering connection staleness

Release 1.3.1 (5th April 2018)

  • Fixed video source negotiation error caused by camera with fractional fps
  • Docker suport for RTSP streaming

Release 1.3.0 (15th March 2018)

  • Fixed producer intermittent termination issue for some edge cases involving re-streaming on error.

Release 1.2.3 (1st March 2018)

  • Updated install-script to fix the local certificate trust issue for curl.
  • Added steps in README troubleshooting section for curl trust issues.

Release 1.2.2 (March 2018)

  • Remove open-source dependencies from KinesisVideoProducerJNI native library. java-install-script can be used to build KinesisVideoProducerJNI native library fast.
  • README note improved.

Release 1.2.1 (February 2018)

  • Bug fix for producer timestamp video playback in the console should be fixed if proper timestamp is provided to SDK. Current setting in sample app uses Gstreamer frame timecode and relative timestamp (used by SDK).
  • install-script is updated to automatically detect OS version and avoid dependency issue on Mac High Sierra and Ubuntu 17.10.
  • Known issue: Producer timestamp mode video playback in console will not work if GStreamer demoapp is configured to use frame timecode and absolute timestamp (used by SDK).

Release 1.2.0 (February 2018)

  • Bug fixes and performance enhancement
  • Streaming error recovery improvements
  • Minor API changes:
    • create stream APIs return shared pointers instead of unique pointers
    • Addition of StreamClosed callback to notify the caller application when the stream is finished draining the existing buffered frames before closing in the graceful termination case.

Release 1.1.3 (February 2018)

  • Added RTSP Demo Sample
  • Run the demo using:
AWS_ACCESS_KEY_ID=<MYACCESSKEYID> AWS_SECRET_ACCESS_KEY=<MYSECRETKEY> ./kinesis_video_gstreamer_sample_rtsp_app <rtspurl> <stream-name>

Release 1.1.2 (January 2018)

  • Allowed devices to output h.264 streams directly
  • The user can also supply a streaming resolution through command line arguments.
    • If resolution is provided then the sample will try to check if the camera supports that resolution. If it does then streaming starts; else, it will fail with an error msg "Resolution not supported"
    • If no resolution is specified, the demo will try to use resolutions 1920x1080, 1280x720 and 640x480 in that order (highest resolution first)and will start streaming once the camera supported resolution is detected.
  • Known issues:
    • When streaming on raspberry pi. Some green artifacts might be observed on the preview screen. Reducing the resolution can fix the issue.

Release 1.1.1 (December 2017)

  • Fix USB webcam support
  • Known issues:
    • If USB webcam doesn't support 720p, then gstreamer negotiation will fail. Trying lower resolution as mentioned in Troubleshooting may fix this issue.

Release 1.1.0 (December 2017)

  • Addition of a received application ACK notification callback
  • Lifecycle management improvements
  • Exposed failure on progressive back-off/retry logic
  • Hardening/fixing various edge-cases
  • Fixing Raspberry PI frame dropping issue

Release 1.0.0 (November 2017)

  • First release of the Amazon Kinesis Video Producer SDK for Cpp.
  • Known issues:
    • Missing build scripts for Windows-based systems.
    • Missing cross-compile option.
    • Sample application/unit tests can't handle buffer pressures properly - simple print in debug log.

Documentation

Kinesis Video Producer SDK CPP

amazon-kinesis-video-streams-producer-sdk-cpp's People

Contributors

bdhandap avatar chehefen avatar hyandell avatar iann0036 avatar luiscosio avatar mushmal avatar neino3 avatar unicornss avatar

Stargazers

 avatar

Watchers

 avatar

Forkers

sofiaisha

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.