概要
YouTube Data API(v3)で検索からYoutubeデータ取得し、iframeで動画を埋め込みたい。
公式リファレンス
・YouTube Data API(v3)
・IFrame Player API
前提
・node.jsとnpm
・Youtube APIのアクセスkey
準備
create-react-appで始めていきます。
$ create-react-app project
$ cd project
$ npm start
public/srcにcomponentsディレクトリを追加して、下記の構成にする(各ディレクトリ以下はindex.js)
components
├── Header
└── Youtube
Youtube APIからデータ取得
初めにAPIからデータをaxiosを使って取得します。
axiosのインストール
$ npm install axios --save
App.jsを編集して、とりあえず以下の条件で取得できるか試してみます。
・ 検索ワード: Create-React-APP
・ 検索数は: 3
期待する検索結果のJSON構造はこの形式
{
"kind": "youtube#searchResult",
"etag": etag,
"id": {
"kind": string,
"videoId": string,
"channelId": string,
"playlistId": string
},
"snippet": {
"publishedAt": datetime,
"channelId": string,
"title": string,
"description": string,
"thumbnails": {
(key): {
"url": string,
"width": unsigned integer,
"height": unsigned integer
}
},
"channelTitle": string
}
}
App.js編集
import React from 'react';
import axios from 'axios';
const YOUTUBE_API_KEY = process.env.REACT_APP_YOUTUBE_API_KEY;
export default class App extends React.Component {
state = {
videos: [],
keyword: 'Create-React-APP'
}
componentDidMount() {
const url = `https://www.googleapis.com/youtube/v3/search?type=video&part=snippet&q=${this.state.keyword}&maxResults=3&key=${YOUTUBE_API_KEY}`;
axios
.get(url)
.then(response => {
this.setState({
videos: response.data.items,
});
})
.catch(() => {
console.log('通信に失敗しました');
});
}
render() {
console.log(this.state.videos)
return (
<>
</>
)
}
}
create-react-appでは、gitignoreにデフォルトでenv.localが入っているので.env.localを作成してここにアクセスキーを記述する。
REACT_APPを前につける必要があり、JS側では記述したKeyの名前の先頭にprocess.envをつけることで取得できる
# API
REACT_APP_YOUTUBE_API_KEY = '自分のアクセスキー'
反映する為に立ち上げ直す
$ npm start
条件通り取得できています
検索フォームの作成
では、検索フォームで入力したキーワードから取得できるようにしていきます。
再度App.jsの修正します。
APIのパラメータに検索フォームの値を使いたいのでのonSerchYoutube関数を記述し、値を受け取る為Header/index.jsにpropsとして渡します。
import React from 'react';
import axios from 'axios';
import Header from './components/Header';
const YOUTUBE_API_KEY = process.env.REACT_APP_YOUTUBE_API_KEY;
export default class App extends React.Component {
state = {
videos: [],
}
onSerchYoutube = (keyword) => {
const url = `https://www.googleapis.com/youtube/v3/search?type=video&part=snippet&q=${keyword}&maxResults=3&key=${YOUTUBE_API_KEY}`;
axios
.get(url)
.then(response => {
this.setState({
videos: response.data.items,
});
})
.catch(() => {
console.log('通信に失敗しました');
});
}
render() {
return (
<>
<Header onSerchYoutube={this.onSerchYoutube} />
</>
)
}
}
Header/index.jsに検索フォームを置いていきます。
YouTube APIではクォータの使用量が決まっており、使用量を考えなければ、一日の上限を超え制限がかかる恐れが有ります。
検索フォームでは、onChangeする度にAPIを呼び出されてしまうので、lodashのdebounceを活用し制限します。
lodashインストール
$ npm install --save lodash
debounceは更新中は関数を呼び出さずに、任意の時間内で更新されなかった時、関数を実行するようにできます。今回は0.2秒の待ち時間を与えます。
参考: https://qiita.com/waterada/items/986660d31bc107dbd91c
import React from 'react';
import _ from 'lodash';
export default class Header extends React.Component {
state = {
keyword: "",
};
handleChangeInput = (e) => {
this.setState({keyword: e.target.value});
this._debounce(e.target.value)
}
_debounce = _.debounce(value => {
this.props.onSerchYoutube(value);
},200);
render() {
return (
<div style={{marginTop: '20px', textAlign:'center'}}>
<input
onChange={this.handleChangeInput}
value={this.state.keyword}
/>
</div>
)
}
}
これで検索ワードからYoutubeのデータが取得できました。
YouTubeを埋め込む
データからYouTubeを埋め込んでいきます。
Youtube/index.jsにstateのvideos渡すようにApp.jsを編集。
// 追加
import Youtube from './components/Youtube';
...
render() {
return (
<>
<Header onSerchYoutube={this.onSerchYoutube} />
{/* 追加 */}
<Youtube videos={this.state.videos}/>
</>
)
}
APIリファレンスIFrame Player APIから
<iframe id="ytplayer" type="text/html" width="640" height="360"
src="http://www.youtube.com/embed/M7lc1UVf-VE?autoplay=1&origin=http://example.com"
frameborder="0"/>
iframeタグのurlにpropsをmapした各videoのvideoIdを入れる。
Youtube/index.jsの作成
import React from 'react';
const Youtube = (props) => {
const video = props.videos.map((video) => {
const url = 'https://www.youtube.com/embed/' + video.id.videoId;
return (
<div style={{margin: '20px', textAlign: 'center'}}>
<iframe
id="ytplayer"
type="ytplayer"
width="480"
height="270"
src={url}
frameborder="0"
/>
</div>
)
});
return (
<div style={{marginTop: '10px'}}>
{video}
</div>
)
}
export default Youtube;
最終的な動き
これでReactでYoutubeデータの取得から埋め込みまで出来ました。
以上です。