Giter Site home page Giter Site logo

lonelycpp / react-native-youtube-iframe Goto Github PK

View Code? Open in Web Editor NEW
563.0 7.0 142.0 11.41 MB

A wrapper of the Youtube-iframe API built for react native.

Home Page: https://lonelycpp.github.io/react-native-youtube-iframe/

License: MIT License

JavaScript 73.39% CSS 2.53% HTML 24.08%
youtube react-native iframe youtube-api youtube-player youtube-video android ios expo

react-native-youtube-iframe's People

Contributors

1000ship avatar bang88 avatar bastianspirek avatar ddaaggeett avatar dependabot[bot] avatar dpwilhelmsen avatar gomesluis479 avatar hoangvvo avatar jonesparaz avatar kardysm avatar lonelycpp avatar maydna avatar orel91 avatar oxyii avatar polcats avatar ralph-dev avatar tasugi avatar todorone avatar wkoutre avatar yannickleroux avatar yupeng-li 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

react-native-youtube-iframe's Issues

Player in offline mode never triggers onError

Describe the bug
I'm trying to handle scenarios where the user navigates to a screen where the player is being used and for some reason the video fails to load or is there a network failure such as, for example the wifi being down, I expected the onError to trigger but somehow it never does

To Reproduce

<YoutubePlayer
    onError={() => {
        console.log('###### Error loading video #######')
    }}
    onReady={() => console.log('############# ready ################')}
    onChangeState={event => console.log('s######  state change ###### ', event)}
    play
    webViewStyle={Styles.videoPlayer}
    videoId={videoId}
    webViewProps={{
        onHttpError: () => {
            console.log('###### on onHttpError from webview #######')
        },
        onError: () => {
            console.log('###### on Error from webview #######')
        },
    }}
/>

Expected behavior
I expected the onError to trigger if for some reason the video failed to load

Smartphone (please complete the following information):

  • Device: Huawei Mate 10 lite
  • OS + version: Android 8.0.0
  • react-native-youtube-iframe 1.2.4
  • react-native-webview 10.2.3
  • react-navite 0.59.9

Overlay Component over fullscreen Youtube Video?

Is there a way to overlay something on the player when it is in fullscreen mode?
I know it can easily be done when it's in the normal form by using position: absolute, but the fullscreen mode itself is kind of an overlay, so how can I get my components on top?

Video not visible on Android

The player is launched by clicking on a thumbnail in my React Native app (I'm using Expo) and works perfectly fine in iOs.
As soon as I click the video loads and starts playing as expected.

On Android, everything works the same but I can only hear the sound therefore the video is played but it is not visible.

Are you aware of any issues? Any recommended fixes?

Thanks

Is it possible to launch fullscreen?

Hi,

For UX reasons, I would prefer the video to launch full screen. I'm displaying videos that would not really be interesting if not full screen.

I'm currently using React Native Youtube for that but it has some issues, like the fact that it is impossible to partially cover the video. I would happily switch to React Native Youtube Iframe if I can launch full screen by default.

Regards

Hide the Top Info Bar from Video

Hi @LonelyCpp,

I am looking for a way to hide the top video info bar from the video. I went through the docs and couldn't find a solution. Is there any way to hide the top info bar on both the platforms?

Can you please help?

Thanks in advance

Fullscreen enabled on iOS but disabled on Android

For all of the videos I've tried, the fullscreen button is enabled on iOS but disabled on Android. Sample code below:

<YoutubePlayer
            videoId={"c8deRYotdng"} // The YouTube video ID
            play
            onError={this.onYoutubeError}
            height={height + 20}
            width={screenWidth + 20}
            initialPlayerParams={{
              preventFullScreen: false,
              iv_load_policy: 3, 
              modestbranding: 1,
              rel: 0
            }}
          />

ios stability issue

hi. i have problems with ios devices. on android there is no problem btw.

i tried with two android and two ios devices. For example on same network, ios devices start video 1 min (sometimes less but avarage it 1 min) later. takes too much time to buffer. i thought the issue was network but it's not.

Bugs

Using expo.

Android:

  1. When you click the play icon over the video, the video state changes to "playing" then immediately switches back to "paused". The video duration indicator continues to run.

Expo web:

  1. Does not work
<YoutubePlayer
  ref={playerRef}
  height={Layout.imageWidth}
  width={Layout.imageWidth}
  videoId={video.videoId}
  play={playing}
  onChangeState={event => console.log(event)}   
  onReady={() => console.log("ready")}
  onError={e => console.log(e)}
  onPlaybackQualityChange={q => console.log(q)}
  volume={50}
  playbackRate={1}
  playerParams={{
     cc_lang_pref: "us",
     showClosedCaptions: true
  }}
/>

Controlling the native YouTube play button

I'm using it with autoplay false as I have a gallery of videos.

Is there any way to hide the big red YouTube play button? Since I have to use a small size to begin with (w 200, h 130), that button looks pretty big.
Or at least can I control the size of that button?

Thanks

playerParams not working?

Seems no matter what I do on iOS, player params aren't working!

      <YoutubePlayer
        height={"100%"}
        width={"100%"}
        ref={playerRef}
        videoId={"AVAc1gYLZK0"}
        play={playing}
        onChangeState={event => console.log(event)}
        onReady={() => console.log("ready")}
        onError={e => console.log(e)}
        onPlaybackQualityChange={q => console.log(q)}
        volume={50}
        playbackRate={1}
        playerParams={{
          preventFullScreen: true,
          start: 25,
        }}
      />

The above code doesn't actually prevent full screen i still am able to toggle full screen. Working in iOS w/ Expo.

Dynamically Append PlayList doesn't update Youtube Playlist

Describe the bug
Dynamically Append PlayList doesn't update Youtube Playlist.

To Reproduce
Add state variable for list of Video IDs, and append the list dynamically. Use that state variable in the Player PlayList.

...
this.state = {
      playList:["tAPVdPLCvYU"],
}
...
<YoutubePlayer
              ref={c => this.playerRef = c}
              height="100%"
              width="100%"
              playList={this.state.playList}
              play={false}
              onChangeState={this.onVideoChangeState}
              onReady={this.onVideoReady}
              onError={e => console.log("OnError",e)}
              onPlaybackQualityChange={q => console.log("OnQualityChange:",q)}
              volume={100}
              playbackRate={1}
              initialPlayerParams={{
                cc_lang_pref: "us",
                showClosedCaptions: true,
                preventFullScreen: true,
              }}
            />

Expected behavior
Youtube playlist should be updated.

[Android] Fullscreen mode not working

Describe the bug
Even though I have set allowsFullscreenVideo: true within webViewProps the video is still being playing in regular mode (I think it's called inline) on Android.

Smartphone (please complete the following information):

  • Device: Pixel 3
  • OS + version: Android 9 (Pie)
  • react-native-youtube-iframe 1.2.4
  • react-native-webview 10.3.1
  • react-native 0.62.2

Additional context

<YoutubePlayer
          play={playing}
          height={75}
          width={150}
          videoId={YOUTUBE_VIDEO_ID}
          webViewProps={{
            allowsInlineMediaPlayback: false,
            allowsFullscreenVideo: true,
          }}
          onChangeState={state => {
            if (state === 'paused' || state === 'ended') {
              setPlaying(false);
            }
          }}
          initialPlayerParams={{
            modestbranding: true,
          }}
        />

Fullscreen control is hide on small width devices.

Describe the bug
The fullscreen control button is showing on small size devices like iPhone 6, 8(The main issue is small screen width not the device). Getting an issue in iPhone only as in the android progress bar is at the bottom after time, volume, and full-screen button so no issue.

To Reproduce
In the YoutubePlayer(In iPhone device/simulator) If set height={180} and width={348} fullscreen button is showing but if reduce the width to width={328} at that time it will not show.

Expected behavior
Is there any workaround that I can show play/push button, progress bar/playtime, and fullscreen button only. Basically user can play video in fullscreen mode as well.

Screenshots
Working example(iPhone 8+)
Screen Shot 2020-07-08 at 3 55 27 PM

Not working example(iPhone 8)
Screen Shot 2020-07-08 at 3 55 20 PM

Smartphone (please complete the following information):

  • Device: [iPhone8/8+]
  • OS + version: [iOS 13.5]
  • react-native-youtube-iframe version 1.2.4
  • react-native-webview version 10.3.1
  • Expo verison [not using expo]

Additional context
No.

Sample code

<YoutubePlayer
 height={180}
 width={348}
 videoId={'## video id ##'}
 onChangeState={event => console.log(event)}
 onReady={() => console.log('ready')}
 onError={e => console.log(e)}
 onPlaybackQualityChange={q => console.log(q)}
 volume={50}
 playbackRate={1}
 playerParams={{
  cc_lang_pref: 'us',
  showClosedCaptions: true,
  allowSeekAhead: false //to hide seek control
 }}
/>

iFrame padding/margin cannot be removed?

I am trying to display the player with a width of 100%, however I am not able to remove the margin/padding completely. I tried using width={"100%"} and webViewStyle={{ marginHorizontal: 0, paddingHorizontal: 0}} however there will always be a white space around it. Is there anything else that I can change? I am not sure where this space is coming from.

[help wanted] Detecting fullscreen on iOS

On android a simple fullscreenchange event listener on document detects fullscreen. wkwebview on ios does not play by the rules here ☹️

It seems like webkitfullscreenchange event does not fire when attached to document. It only works if you attach it to the <video /> tag. This <video /> tag unfortunately lives inside the iframe and any attempts to access it will throw a CORS error.

tracking branch if you want to contribute - https://github.com/LonelyCpp/react-native-youtube-iframe/tree/fs-callback

share not working in Android, and How can i disable more videos?

Describe the bug
While trying to share, nothing happens or responding.

To Reproduce
Press share icon.

Expected behavior
Share should work.

Screenshots
If applicable, add screenshots to help explain your problem.

Smartphone (please complete the following information):

  • Device: Redmi note 4
  • OS + version: Android 7
  • react-native-youtube-iframe 1.2.4
  • react-native-webview 7.5.1
  • Expo verison [if using expo]

Additional context
Add any other context about the problem here.
Is there and option to hide share if possible, and also is it possible to hide more videos (Next suggested) once current video ended as nothing happens if i press any suggested video.

onSeek function

How to know if user seek spesific time is there a way to detect it ?

Does onChangeState provides this behaviour ?

Prevent from switching to Youtube app on iOS

Describe the bug
When playing a video on fullscreen and going back to normal mode (inline), after resuming the video instead of keep showing the video from where it was left, the user is taken to the youtube app video channel on iOS...

To Reproduce
Check to code below on an iPhone XR with version 13.5.1

Expected behavior
To resume the video within the app as opposed to switching to youtube app video channel

Smartphone (please complete the following information):

  • Device: iPhone XR
  • OS + version: iOS 13.5.1
  • react-native-youtube-iframe 1.2.4
  • react-native-webview 10.3.1
  • react-native 0.62.2

Additional context

<YoutubePlayer
          play={playing}
          height={75}
          width={150}
          videoId={YOUTUBE_VIDEO_ID}
          webViewProps={{
            allowsInlineMediaPlayback: false,
            allowsFullscreenVideo: true,
          }}
          onChangeState={state => {
            if (state === 'paused' || state === 'ended') {
              setPlaying(false);
            }
          }}
          initialPlayerParams={{
            modestbranding: true,
          }}
        />

Question about the viewport meta tag

Hello! Thanks for writing this plugin! I was using this iframe technique in my application myself and I found this package that put it together nicely. However, after I started using this package, I started to get users complaining about not being able to "zoom in" on videos any more. I thought that was weird, but after looking into it, I guess my old implementation didn't have a maximum-scale set in the viewport meta tag. After removing it, zooming was allowed again.

Is there a way to make that max-scale configurable or removed? Or is this too much of a weird edge case and better handled in a private fork?

Thanks for your time, have a great day!

changing design

I want to hide youtube logo and the 3 dots from the video ,
simply i want users not able to get the video link one way or another.

is it supported ?

Fullscreen in modal

If YoutubePlayer in modal window, when you click fullscreen, you cant see him because he places under modal. Any ideas how to fix this?

Video don't play on android

Hi there,

I have a great hope in your lib, as I need to play two videos in the same page and react-native-youtube doesn't do it for Android.

I installed very easily, it's working great on iOS, but on Android I can't play the video.

Here is my code :

import React from 'react'
import PropTypes from 'prop-types'
import YoutubePlayer from 'react-native-youtube-iframe'
import { withNavigationFocus } from 'react-navigation'
import { getImageSize } from '../utils/images'

const aspectRatio = 9 / 16
const imageSize = getImageSize(aspectRatio)

const Player = ({ videoID, onError, isFocused }) => {
  if (!isFocused) return null
  return (
    <YoutubePlayer
      height={imageSize.height}
      width={imageSize.width}
      videoId={videoID}
      onChangeState={(event) => console.log('Player onChangeState', event)}
      onReady={(e) => console.log('Player onReady', e)}
      onError={(e) => {
        console.log('Player error', e)
        onError(e)
      }}
      onPlaybackQualityChange={(q) => console.log('onPlaybackQualityChange', q)}
      volume={60}
      playbackRate={1}
      playerParams={{}}
    />
  )
}

Player.propTypes = {
  videoID: PropTypes.string.isRequired,
  onError: PropTypes.func,
  isFocused: PropTypes.bool.isRequired,
}
Player.defaultProps = {
  onError: () => null,
}

export default withNavigationFocus(Player)

When I click on the youtube button play, the log is the following:

 LOG  Player onChangeState unstarted
 LOG  Player onChangeState buffering
 LOG  onPlaybackQualityChange large
 LOG  Player onChangeState unstarted

Is there something I'm missing ?

Bad quality

Hello, I'm trying to make a movie app, and I want to display some trailers.

The problem is the quality, it's always set to "small", and I can't change it, I don't have the controls for it.

Here is my code :

import { StyleSheet, View, Dimensions } from 'react-native'
import React from 'react'
import YoutubePlayer from 'react-native-youtube-iframe'

export default class Trailer extends React.Component {

    constructor(props) {
        super(props)
        this.state = {
            playing: true,
            videoID: this.props.route.params.videoID,
            width: Dimensions.get('window').width,
        }
    }

    onLayout = (event) => {
        this.setState({ width: event.nativeEvent.layout.width })
    }

    render() {
        return (
            <View style={styles.mainContainer} onLayout={this.onLayout.bind(this)}>
                <YoutubePlayer
                    height={this.state.width * (9 / 16)}
                    width={this.state.width}
                    videoId={this.state.videoID}
                    play={this.state.playing}
                    onPlaybackQualityChange={q => console.log(q)}
                    initialPlayerParams={{
                        rel: 0
                    }}
                />
            </View>
        )
    }

}

const styles = StyleSheet.create({
    mainContainer: {
        flex: 1,
        justifyContent: "center",
        alignItems: "center",
        backgroundColor: "#000000"
    },
});

Does someone have an idea to have a better quality ? Already try a webview, but they turnoff the forced quality.

Thanks !

UIWebView is deprecated

Describe the bug
A clear and concise description of what the bug is.
Screen Shot 2020-07-28 at 09 13 49

To Reproduce
Upload to appstore, would received feedback from apple.
Expected behavior
Should replace UIWebView by WKWebView
Screenshots
If applicable, add screenshots to help explain your problem.

Smartphone (please complete the following information):

  • Device: [e.g. iPhone6]
  • OS + version: [e.g. iOS 13.5 | Android 10]
  • react-native-youtube-iframe1.2.4
  • react-native-webview 10..3.2
  • Expo verison [if using expo]

Additional context
Add any other context about the problem here.

[help wanted] Want to play video in loop

Hey First of all thank you for this wonderful package.

Is there any option by which we can play video in loop because i dont want to show suggested video screen at the end of the video. Or something to not show suggested video at the end.

YouTube player volume

Hi, would like to ask if the youtube player's volume output is a bug.
It is in 100 but the audio output is low (both iOS and android)

[help wanted] Detecting fullscreen on iOS

On android a simple fullscreenchange event listener on document detects fullscreen. wkwebview on ios does not play by the rules here ☹️

It seems like webkitfullscreenchange event does not fire when attached to document. It only works if you attach it to the <video /> tag. This <video /> tag unfortunately lives inside the iframe and any attempts to access it will throw a CORS error.

tracking branch if you want to contribute - https://github.com/LonelyCpp/react-native-youtube-iframe/tree/fs-callback

Missing onProgress

I want to setup my own seekbar and need an onProgress callback. Is this possible?

How can I use realtime currentTime of YouTube Video?

Hi, LonelyCpp.
I'm actually trying to use your component.
It's more stable and easier than react-native-youtube. It's great!
I need to synchronize the state with YouTube Video currentTime.
But, I cannot find how to do that.
I tried to use setInterval and it worked, but currentTime was a float number.
So, I use toFixed, and Math.floor, then I can see the short change from float to integer number.
I need the function like elapsed time in this demo https://cookpete.com/react-player/.
May I ask you the solution for this problem?

[help wanter] Iframe issue on Back from full screen

Hey,

Whenever i came back from fullscreen mode and with paused or playing, it show the complete youtube frame. attached screenshot of the same.

Note: Facing this issue in Latest android version (android 10), not in old ones.

WhatsApp Image 2020-07-28 at 6 10 56 PM

Video not visible on android emulator

This could be similar to #26, but I'm not trying to get the video to work with a Modal button, I'm just trying to display the Youtube video on my screen.

When screen loads, thumbnail loads properly

Screenshot_1591137105

But when trying to play video:

Screenshot_1591137111

Here is a video from Google Pixel 2 API 27 Simulator, audio works great, and you can press all the buttons, just the video doesnt show. It also works great on iOS with same code.

ezgif com-video-to-gif

Here is the code:


const DeepDiveYoutubeItem = ({ deepDiveItem, parentComponentId }) => {

  const SCREEN_WIDTH = Dimensions.get('window').width;

  return (
      <YTPlayer
        height={SCREEN_WIDTH*(9/16)}
        width={SCREEN_WIDTH}
        videoId={deepDiveItem.primary} // 'BHenknGIZPs'
        onError={e => { console.log('e', e); }}
      />
  );
};
export default DeepDiveYoutubeItem;

Disable text selection on iOS

Describe the bug
Blue text selection handles are shown on top of the video

To Reproduce

  1. Tap on the 3 vertical dots icon on the upper right corner of the video iframe
  2. Then click on the Share option
  3. Finally tap on the 3 horizontal dots once and close the overlay from the X icon
  4. Blue text selection handles will appear randomly on top of the video...

Expected behaviour
Text selection should be optional

Screenshots
Untitled

Smartphone (please complete the following information):

  • Device: iPhone 11
  • OS + version: iOS 13.5.1
  • react-native-youtube-iframe 1.2.4
  • react-native-webview 10.3.1
  • react-native 0.62.2

Additional context
I tried to disable the text selection following the info provided here but unfortunately it didn't work:

const INJECTED_JAVASCRIPT = "document.body.style.userSelect = 'none'";
...
<YoutubePlayer
          play={playing}
          height={VIDEO_HEIGHT}
          width={VIDEO_WIDTH}
          videoId="AVAc1gYLZK0"
          initialPlayerParams={{
            modestbranding: true,
          }}
          webViewStyle={styles.webView}
          webViewProps={{
            injectedJavaScript: INJECTED_JAVASCRIPT,
          }}
          onReady={() => setVideoReady(true)}
        />

Player resolution

Hey! I noticed player resolution is always 16:9.
This can be changed?
How?

Thanks!

After exiting fullscreen, the video remains in the "expanded" size

Describe the bug
After I exit out of fullscreen in landscape mode, the youtube video retains the "landscape fullscreen" size. The app also freezes, and all parts of the app except the video becomes untouchable. Even in portrait mode, after exiting fullscreen, the play/pause button is no longer there, and other UI buttons can be seen to be increased in size.

To Reproduce
Exit out of fullscreen in both portrait mode and landscape mode.

Expected behavior
The video should revert back to its original size when exiting fullscreen.

Screenshots
https://streamable.com/y9238r
https://streamable.com/xmxjev

Smartphone (please complete the following information):

  • Device: Reproduced in Android emulator: pixel 2, Physical phones: Oneplus 6, iPhone 8
  • OS + version:
  • react-native-youtube-iframe version : "^1.2.4"
  • react-native-webview version: "8.1.1"
  • Expo verison [if using expo]: "~37.0.3"

Additional context
When reproducing the bug on landscape mode, I get a Warning message from expo: "State updates from the useState() and useReducer() Hooks don't support the second callback...". I can't even expand the warning as it also becomes unresponsive to touch.

Code

import YoutubePlayer from 'react-native-youtube-iframe';

const App = () => {
    const playerRef = useRef(null);
    const [playing, setPlaying] = useState(true);
    const width = useWindowDimensions().width
    const height = width*9/16;

    return (
        <YoutubePlayer
                ref={playerRef}
                height={height}
                width={width}
                videoId={id.video}
                play={playing}
                volume={50}
                playbackRate={1}
                playerParams={{
                    cc_lang_pref: "us",
                    showClosedCaptions: false,
                }}
        />
    )
}

modestbranding not working

Describe the bug
Setting up modestbranding: true doesn't seen to be working neither on iOS nor on Android. Youtube play button is still being displayed...

Smartphone (please complete the following information):

  • Device: any
  • OS + version: iOS 13.5.1 and Android 9
  • react-native-youtube-iframe 1.2.4
  • react-native-webview 10.3.1
  • react-native 0.62.2

Additional context

<YoutubePlayer
          play={playing}
          height={75}
          width={150}
          videoId={YOUTUBE_VIDEO_ID}
          webViewProps={{
            allowsInlineMediaPlayback: false,
            allowsFullscreenVideo: true,
          }}
          onChangeState={state => {
            if (state === 'paused' || state === 'ended') {
              setPlaying(false);
            }
          }}
          initialPlayerParams={{
            modestbranding: true,
          }}
        />

Not working in stack navigator

Controls are disabled in stack navigator
Users cannot pause or play the video when the screen is wrapped under stack navigator.

Would really appreciate your help. Thanks

Background Play

Hi. is there a way keep playing youtube video even if app in background?

Quality Video Youtube is missing

i just copy and paste the example on fresh react-native project,

it is working properly but i realize that video quality is missing, i cannot change the quality.

what is the problem i missed ?

RN : 0.61
react-native-youtube-iframe : 1.2.0

Full screen display is disabled

React Native 0.62
react-native-youtube-iframe 1.2.0
Trying in real android device

I tried this
<YoutubeIframe height={250} videoId={'someVideoId'} initialPlayerParams={{ preventFullScreen: false}} />

It display full screen button, but it is disabled to click.
How can I use display full screen function?

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.