将youtube播放列表变成网站-程序员宅基地

技术标签: python  https  

From Scratch: using Next.js (React), Bulma & Zeit Now

从头开始:立即使用Next.js(React),布尔玛和Zeit

(written in April, posted in august, some stuff might be out of date)

(写于四月,八月发布,有些东西可能已经过时了)

I’m new to front-end. Part of the fun is figuring out small projects to discover new tricks. The later fun comes from showing what I found out in case anyone else wanted to try the same things. This guide uses Next.js (it’s basically react) to build the frontend & backend, we’ll style the app with Bulma, and host it with Zeit Now (hiding our API key so no one hacks us).

我是前端新手。 有趣的部分是找出小型项目以发现新的技巧。 以后的乐趣来自展示我发现的结果,以防其他人想尝试相同的东西。 本指南使用Next.js(基本上是在React)来构建前端和后端,我们将使用Bulma样式化应用程序,并使用Zeit Now托管应用程序(隐藏我们的API密钥,这样就不会有人攻击我们)。

For this project, I’m turning my youtube playlist of drone videos to render a gallery on my website dean.red.

对于这个项目,我将我的YouTube无人机视频播放列表转为在dean.red网站上渲染一个图库

View Demo Github Repo

查看演示Github回购

先决条件 (Pre-requisites)

  • Node.js

    Node.js
  • Signup with Zeit Now and download their CLI

    立即注册Zeit并下载其CLI

入门 (Getting Started)

Let’s get the installation & configuration out of the way first. Let’s start by creating the next.js skeleton.

让我们首先进行安装和配置。 让我们从创建next.js框架开始。

npx create-next-app

Now let’s install the node_modules we’ll be using:

现在,让我们安装将要使用的node_modules:

npm i node-sass bulma dotenv axios

安装样式(布尔玛) (Installing Styling (Bulma))

Let’s setup the styling with node-sass & bulma. Open your package.json configuration file and copy/paste the scripts for css:build & css:watch:

让我们使用node-sass和bulma设置样式。 打开您的package.json配置文件,然后复制/粘贴css:buildcss:watch的脚本:

// package.json"scripts": {"dev": "next dev",
"build": "next build",
"start": "next start","css:build": "node-sass --omit-source-map-url assets/sass/styles.scss static/css/styles.css",
"css:watch": "npm run css:build -- --watch"
}

This script will turn a .SCSS file into a static CSS file. To do this, we need to create the .SCSS file.

该脚本会将.SCSS文件转换为静态CSS文件。 为此,我们需要创建.SCSS文件。

In the folder root, create a new folder called assets, then create a sub-folder called sass, then inside this folder create a file called styles.scss

在文件夹根目录中,创建一个名为asset的新文件夹,然后创建一个名为sass的子文件夹,然后在此文件夹中创建一个名为styles.scss的文件。

Now we can load bulma into styles.scss with the following code:

现在,我们可以使用以下代码将bulma加载到styles.scss中:

// assets/styles/styles.scss@charset "utf-8";
@import '../../node_modules/bulma/bulma.sass';

Next, we’ll build the static .CSS file with styles.scss. In the terminal:

接下来,我们将使用styles.scss构建静态.CSS文件。 在终端中:

npm run css:build
Image for post

This creates a folder called static with the styles.css nested inside.

这将创建一个名为static的文件夹,其中嵌套了styles.css。

Now we can use this styling inside our app. To do so, let’s create a Head component that we can use inside all our pages consistently. Create the file TheHead.js inside the components folder:

现在,我们可以在应用程序内部使用此样式。 为此,我们创建一个Head组件,可以在所有页面中一致地使用它。 在components文件夹内创建文件TheHead.js

// components/TheHead.jsimport Head from 'next/head'export default () => (
<Head>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta charSet="utf-8" />
<title>youtube playlist</title><link rel="stylesheet" type="text/css" href="/static/css/styles.css" />
</Head>
)

Let’s now update pages/index.js by replacing everything with the following code. Notice the import and use of <TheHead /> component.

现在,通过将所有内容替换为以下代码来更新pages / index.js 。 注意<TheHead />组件的导入和使用。

// pages/index.jsimport React, { Component } from 'react'import TheHead from '../components/TheHead'export default class index extends Component {
        
render() {
return (
<div><TheHead />
<section className="section">
<div className="columns">
<div className="column is-8 is-offset-2">
<h1 className="title">
Bulma is installed!
</h1>
<a className="button is-primary">Button Test</a>
</div>
</div>
</section>
</div>
)
}
}

Now let’s see how this looks.

现在,让我们看看它的外观。

npm run css:build
npm run dev
Image for post
If everything was installed correctly, your site should look like this (with the green button).
如果一切都已正确安装,则您的站点应如下所示(带有绿色按钮)。

创建后端 (Creating the Backend)

To use the Youtube API v3, you need to have an API Key. If we used this within the frontend/client, anyone could see the key and hack into our google account. Luckily, Next.js & Zeit Now makes it easy to deploy a backend that can fetch the playlist information without exposing our API Key.

要使用Youtube API v3,您需要具有API密钥。 如果我们在前端/客户端中使用此功能,则任何人都可以看到密钥并入侵我们的Google帐户。 幸运的是,Next.js和Zeit Now使得部署后端很容易,该后端无需公开我们的API密钥即可获取播放列表信息。

设置环境变量 (Setting up the Environment Variables)

Let’s start by configuring our .env files, which allows us to work locally and on production without exposing our keys.

让我们从配置.env文件开始,该文件使我们能够在本地和生产环境中工作而无需公开密钥。

Create a new file in root called next.config.js.

在根目录中创建一个名为next.config.js的新文件

// next.config.jsrequire('dotenv').config()module.exports = {
        
env: {
// Reference a variable that was defined in the .env file and make it available at Build Time
APIKEY: process.env.APIKEY,
PLAYLIST: process.env.PLAYLIST,
},
}

Then create a new file in root called .env

然后在名为.env的根目录中创建一个新文件

APIKEY=keyABC
PLAYLIST=appABC

Then create two new files in root called .nowignore & .gitignore

然后在根目录中创建两个新文件,名为.nowignore.gitignore

// .nowignore
.env
node_modules// .gitignore
.env
node_modules

设置API (Setting up the API)

Next.js makes it easy to setup APIs out of the box (we don’t need express).

Next.js使开箱即用地设置API变得容易(我们不需要express)。

Image for post

Create a new file pages/api/server.js (create a new folder called api inside of pages).

创建一个新文件pages / api / server.js (在页面内部创建一个名为api的新文件夹)。

// pages/api/server.jsimport fetch from 'axios'
import getConfig from 'next/config'const key = process.env.APIKEY
const playlist = process.env.PLAYLIST
const maxResults = 3
const apiURL = `https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&type=video&order=date&maxResults=${maxResults}&playlistId=${playlist}&key=${key}`module.exports = async (req, res) => {
try {
// const result = await fetch(apiURL)
// res.status(200).json(result.data)
res.status(200).json(apiURL) } catch (err) {
res.status(500).json('Whoops, something went wrong')
}
}

Save the file, then restart your server (ctrl-c & npm run dev). Then visit localhost:3000/api/server. You should get the following response.

保存文件,然后重新启动服务器(ctrl-c和npm run dev)。 然后访问localhost:3000 / api / server 。 您应该得到以下答复。

https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&type=video&order=date&maxResults=3&playlistId=appABC&key=keyABC

If you see appABC & keyABC, then your environment variables are working!

如果看到appABCkeyABC ,那么您的环境变量正在运行!

设置API密钥和播放列表 (Setup the API Key & Playlist)

Head over and sign-in to: https://console.developers.google.com/ and create a new project

前往并登录: https : //console.developers.google.com/并创建一个新项目

Image for post
Image for post

Select & create credentials (API key)

选择并创建凭据(API密钥)

Image for post

Take the newly generated API key and paste it into your .env file. This will then be available throughout our app.

使用新生成的API密钥并将其粘贴到您的.env文件中。 然后,它将在整个应用程序中可用。

// .envAPIKEY=PasteYourKeyHere
PLAYLIST=appABC

On your Google Console, navigate to your dashboard and enable API & Services.

在您的Google控制台上,导航到您的仪表板并启用API和服务。

Image for post

Search for “Youtube” and then select & enable Youtube Data API v3

搜索“ Youtube”,然后选择并启用Youtube Data API v3

Image for post

Now let’s grab the playlist ID. Navigate to your youtube playlists. Copy the URL and then paste the ID into your .env file:

现在,让我们获取播放列表ID。 导航到您的youtube播放列表。 复制URL,然后将ID粘贴到您的.env文件中:

Image for post
// url of the youtube playlisthttps://www.youtube.com/playlist?list=PL1i-TpHn0XgwXFgOmP_axN4mxE-vVA0gt// .envAPIKEY=PasteYourKeyHere
PLAYLIST=PL1i-TpHn0XgwXFgOmP_axN4mxE-vVA0gt

Open up your /api/server.js file and uncomment the code we hid earlier. We can comment out res.status(200).json(apiURL) so that we can use it for debugging later if needed.

打开/api/server.js文件,然后取消注释我们之前隐藏的代码。 我们可以注释掉res.status(200).json(apiURL),以便以后在需要时将其用于调试。

// pages/api/server.jsimport fetch from 'axios'
import getConfig from 'next/config'const key = process.env.APIKEY
const playlist = process.env.PLAYLIST
const maxResults = 3
const apiURL = `https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&type=video&order=date&maxResults=${maxResults}&playlistId=${playlist}&key=${key}`module.exports = async (req, res) => {
try {
const result = await fetch(apiURL)
res.status(200).json(result.data)
// res.status(200).json(apiURL)} catch (err) {
res.status(500).json('Whoops, something went wrong')
}
}

Save everything & restart your server (Ctrl-C and then npm run dev). Once compiled, visit localhost:3000/api/server and you should get a json like the following:

保存所有内容并重新启动服务器(Ctrl-C,然后npm run dev)。 编译后,访问localhost:3000 / api / server,您应该得到一个类似于以下内容的json:

{"kind":"youtube#playlistItemListResponse","etag":"\"p4VTdlkQv3HQeTEaXgvLePAydmU/ONj3fEgwTdkCNzYy4qEjt_a2i_A\"","nextPageToken":"CAMQAA","pageInfo":{"totalResults":20,"resultsPerPage":3},"items":[{"kind":"youtube#playlistItem","etag":"\"p4VTdlkQv3HQeTEaXgvLePAydmU/BaaKN-5F21x53nw6GEnHSwaNtDw\"","id":"UEwxaS1UcEhuMFhnd1hGZ09tUF9heE40bXhFLXZWQTBndC5ENDU4Q0M4RDExNzM1Mjcy","snippet":{"publishedAt":"2019-02-17T00:57:40.000Z","channelId":"UCNLJ9gzT_wVT8wbX8OVuaCA","title":"Brunssummerheide – MAVIC AIR Drone","description":"this feeling by..( ... snipping to save room ... )

Congratulations!!! You have successfully created a backend that can securely grab videos from a youtube playlist! Now we can call this data throughout our app via this custom backend.

恭喜!!! 您已经成功创建了一个可以安全地从youtube播放列表中抓取视频的后端! 现在,我们可以通过此自定义后端在整个应用程序中调用此数据。

创建前端 (Creating the FrontEnd)

Now that we have a backend that can fetch a json of videos from a youtube playlist, we can now use that information to dynamically generate a page of videos.

现在我们有了一个可以从youtube播放列表中获取视频json的后端,现在我们可以使用该信息动态生成视频页面。

Image for post

To get started, let’s create a function in the frontend that grabs the data from our backend. Start by creating a new folder in root called lib. Inside this folder, create a file called db.js

首先,让我们在前端创建一个函数以从后端获取数据。 首先在根目录下创建一个名为lib的新文件夹。 在此文件夹中,创建一个名为db.js的文件

// lib/db.jsimport fetch from 'axios'async function getResults () {
        
const apiURL = `/api/server`try {
const result = await fetch(apiURL)
return result.data.items
} catch (err) {
console.log(`Shoot! You hit an error: ${err}`)
}
}export { getResults }

Now we can use getResults() to grab the playlist data without exposing our api key!

现在我们可以使用getResults()来获取播放列表数据,而无需暴露我们的api键!

Head back over to index.js and import getResults() and then console.log the results in componentDidMount(){} above render(). This will call getResults() immediately when the page loads.

返回到index.js并导入getResults() ,然后将结果记录在render()上方的componentDidMount(){}中 。 页面加载后,将立即调用getResults()。

import React, { Component } from 'react'
import TheHead from '../components/TheHead'import { getResults } from '../lib/db'export default class index extends Component { componentDidMount () {
getResults().then(data => {
console.log('videos: ', data)
})
}

render () {
return (
(... rest of app ... )

Now if we head over to our homepage and open the browser console, we can see the json is available for us to use:

现在,如果我们转到主页并打开浏览器控制台,我们可以看到可以使用json了:

Image for post

创建可重复的视频组件 (Creating the repeatable Video component)

Now that we have an array of objects, let’s prepare a component that can take this information and create a card with a thumbnail, link to the video, and title of video.

现在我们有了对象数组,让我们准备一个组件,该组件可以获取此信息,并创建带有缩略图,视频链接和视频标题的卡片。

Create a new file Video.js inside the components folder.

在components文件夹内创建一个新文件Video.js

// components/Video.jsimport React, { Component, Fragment } from 'react'export default class Video extends Component {
        
constructor (props) {
super(props)
}render () {
const vid = this.props.data.snippet
console.log(vid) const thumbnailURL = vid.thumbnails.high.url
const { title, description } = vid
const vidID = vid.resourceId.videoId
const vidURL = `https://youtu.be/${vidID}`return (
<Fragment>
<div className='card'>
<div className='card-image'>
<figure className='image is-4by3'>
<a href={vidURL}>
<img src={thumbnailURL} alt='Placeholder image' />
</a>
</figure>
</div>
<div className='card-content'>
<div className='media'>
<div className='media-content'>
<p className='title is-4'>{title}</p>
</div>
</div>
<div className='content'>{description}</div>
</div>
</div>
<style jsx>{`
.card {
margin-bottom: 2rem !important;
}
`}</style>
</Fragment>
)
}
}

Now that we have this Video component, we can edit our index.js to loop over this component with the json we have. We’ll add a constructor to index.js so that we can set the state with the data from the json. Then we can map the Video component for as many videos are in the playlist.

现在我们有了这个Video组件,我们可以编辑index.js以使用我们拥有的json在该组件上循环。 我们将在index.js中添加一个构造函数,以便可以使用json中的数据设置状态。 然后,我们可以将视频组件映射到播放列表中的多个视频。

// pages/index.jsimport React, { Component } from 'react'
import TheHead from '../components/TheHead'
import Video from '../components/Video'
import { getResults } from '../lib/db'export default class index extends Component {
constructor (props) {
super(props)
this.state = {
videos: []
}
}componentDidMount () {
getResults().then(data => {
this.setState({ videos: data })
})
}
render () {
return (
<div>
<TheHead />
<section className='section'>
<div className='columns'>
<div className='column is-4 is-offset-4'>
<h1 className='title'>Drone Videos</h1>
{this.state.videos.map((vid, i) => (
<Video key={i} data={vid} />
))}
</div>
</div>
</section>
</div>
)
}
}

Save your project and restart your server. Your homepage should now load the videos in cards!

保存您的项目并重新启动服务器。 现在,您的主页应将视频加载到卡片中!

Image for post
View the Website Demo: https://youtubeplaylist.now.sh/
查看网站演示: https : //youtubeplaylist.now.sh/

部署网站 (Deploy the Website)

Now our app is ready to be deployed for the world to see. Before we do so, we’ll need to add Secrets to our Zeit Now accounts. This will replace the API Key & Playlist ID values held in our .env file.

现在,我们的应用已准备就绪,可以进行部署,以供全世界查看。 在我们这样做之前,我们需要将Secrets添加到我们的Zeit Now帐户中。 这将替换保存在我们的.env文件中的API密钥和播放列表ID值。

Create a new file in root called now.json. This replaces our env variables with secrets we’re about to make on now.

在根目录中创建一个名为now.json的新文件 这会将我们的env变量替换为我们现在要制作的秘密。

// now.json{
        
"build": {
"env": {
"APIKEY": "@ytplaylist-key",
"PLAYLIST": "@ytplaylist-playlist"
}
}
}

Next, open your terminal and load in your secrets with the following commands. Replace the API Key & Playlist with the values from your .env file.

接下来,打开您的终端并使用以下命令加载您的机密。 用.env文件中的值替换API密钥和播放列表。

now secrets add ytplaylist-key PasteYourAPIKeyHerenow secrets add ytplaylist-playlist PasteYourPlaylistIDHere

Once you add your secrets, you can deploy your project from the terminal. navigate to your project and from the root, type:

添加秘密后,您可以从终端部署项目。 导航到您的项目,然后从根目录键入:

now

Congratulations!!! Your app is now available! View the demo here.

恭喜!!! 您的应用现已可用! 在此处查看演示。

翻译自: https://medium.com/@dmasley/turn-a-youtube-playlist-into-a-website-98235f9230aa

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_26723981/article/details/108898830

智能推荐

5个超厉害的资源搜索网站,每一款都可以让你的资源满满!_最全资源搜索引擎-程序员宅基地

文章浏览阅读1.6w次,点赞8次,收藏41次。生活中我们无时不刻不都要在网站搜索资源,但就是缺少一个趁手的资源搜索网站,如果有一个比较好的资源搜索网站可以帮助我们节省一大半时间!今天小编在这里为大家分享5款超厉害的资源搜索网站,每一款都可以让你的资源丰富精彩!网盘传奇一款最有效的网盘资源搜索网站你还在为找网站里面的资源而烦恼找不到什么合适的工具而烦恼吗?这款网站传奇网站汇聚了4853w个资源,并且它每一天都会持续更新资源;..._最全资源搜索引擎

Book类的设计(Java)_6-1 book类的设计java-程序员宅基地

文章浏览阅读4.5k次,点赞5次,收藏18次。阅读测试程序,设计一个Book类。函数接口定义:class Book{}该类有 四个私有属性 分别是 书籍名称、 价格、 作者、 出版年份,以及相应的set 与get方法;该类有一个含有四个参数的构造方法,这四个参数依次是 书籍名称、 价格、 作者、 出版年份 。裁判测试程序样例:import java.util.*;public class Main { public static void main(String[] args) { List <Book>_6-1 book类的设计java

基于微信小程序的校园导航小程序设计与实现_校园导航微信小程序系统的设计与实现-程序员宅基地

文章浏览阅读613次,点赞28次,收藏27次。相比于以前的传统手工管理方式,智能化的管理方式可以大幅降低学校的运营人员成本,实现了校园导航的标准化、制度化、程序化的管理,有效地防止了校园导航的随意管理,提高了信息的处理速度和精确度,能够及时、准确地查询和修正建筑速看等信息。课题主要采用微信小程序、SpringBoot架构技术,前端以小程序页面呈现给学生,结合后台java语言使页面更加完善,后台使用MySQL数据库进行数据存储。微信小程序主要包括学生信息、校园简介、建筑速看、系统信息等功能,从而实现智能化的管理方式,提高工作效率。

有状态和无状态登录

传统上用户登陆状态会以 Session 的形式保存在服务器上,而 Session ID 则保存在前端的 Cookie 中;而使用 JWT 以后,用户的认证信息将会以 Token 的形式保存在前端,服务器不需要保存任何的用户状态,这也就是为什么 JWT 被称为无状态登陆的原因,无状态登陆最大的优势就是完美支持分布式部署,可以使用一个 Token 发送给不同的服务器,而所有的服务器都会返回同样的结果。有状态和无状态最大的区别就是服务端会不会保存客户端的信息。

九大角度全方位对比Android、iOS开发_ios 开发角度-程序员宅基地

文章浏览阅读784次。发表于10小时前| 2674次阅读| 来源TechCrunch| 19 条评论| 作者Jon EvansiOSAndroid应用开发产品编程语言JavaObjective-C摘要:即便Android市场份额已经超过80%,对于开发者来说,使用哪一个平台做开发仍然很难选择。本文从开发环境、配置、UX设计、语言、API、网络、分享、碎片化、发布等九个方面把Android和iOS_ios 开发角度

搜索引擎的发展历史

搜索引擎的发展历史可以追溯到20世纪90年代初,随着互联网的快速发展和信息量的急剧增加,人们开始感受到了获取和管理信息的挑战。这些阶段展示了搜索引擎在技术和商业模式上的不断演进,以满足用户对信息获取的不断增长的需求。

随便推点

控制对象的特性_控制对象特性-程序员宅基地

文章浏览阅读990次。对象特性是指控制对象的输出参数和输入参数之间的相互作用规律。放大系数K描述控制对象特性的静态特性参数。它的意义是:输出量的变化量和输入量的变化量之比。时间常数T当输入量发生变化后,所引起输出量变化的快慢。(动态参数) ..._控制对象特性

FRP搭建内网穿透(亲测有效)_locyanfrp-程序员宅基地

文章浏览阅读5.7w次,点赞50次,收藏276次。FRP搭建内网穿透1.概述:frp可以通过有公网IP的的服务器将内网的主机暴露给互联网,从而实现通过外网能直接访问到内网主机;frp有服务端和客户端,服务端需要装在有公网ip的服务器上,客户端装在内网主机上。2.简单的图解:3.准备工作:1.一个域名(www.test.xyz)2.一台有公网IP的服务器(阿里云、腾讯云等都行)3.一台内网主机4.下载frp,选择适合的版本下载解压如下:我这里服务器端和客户端都放在了/usr/local/frp/目录下4.执行命令# 服务器端给执_locyanfrp

UVA 12534 - Binary Matrix 2 (网络流‘最小费用最大流’ZKW)_uva12534-程序员宅基地

文章浏览阅读687次。题目:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=93745#problem/A题意:给出r*c的01矩阵,可以翻转格子使得0表成1,1变成0,求出最小的步数使得每一行中1的个数相等,每一列中1的个数相等。思路:网络流。容量可以保证每一行和每一列的1的个数相等,费用可以算出最小步数。行向列建边,如果该格子是_uva12534

免费SSL证书_csdn alphassl免费申请-程序员宅基地

文章浏览阅读504次。1、Let's Encrypt 90天,支持泛域名2、Buypass:https://www.buypass.com/ssl/resources/go-ssl-technical-specification6个月,单域名3、AlwaysOnSLL:https://alwaysonssl.com/ 1年,单域名 可参考蜗牛(wn789)4、TrustAsia5、Alpha..._csdn alphassl免费申请

测试算法的性能(以选择排序为例)_算法性能测试-程序员宅基地

文章浏览阅读1.6k次。测试算法的性能 很多时候我们需要对算法的性能进行测试,最简单的方式是看算法在特定的数据集上的执行时间,简单的测试算法性能的函数实现见testSort()。【思想】:用clock_t计算某排序算法所需的时间,(endTime - startTime)/ CLOCKS_PER_SEC来表示执行了多少秒。【关于宏CLOCKS_PER_SEC】:以下摘自百度百科,“CLOCKS_PE_算法性能测试

Lane Detection_lanedetectionlite-程序员宅基地

文章浏览阅读1.2k次。fromhttps://towardsdatascience.com/finding-lane-lines-simple-pipeline-for-lane-detection-d02b62e7572bIdentifying lanes of the road is very common task that human driver performs. This is important ..._lanedetectionlite

推荐文章

热门文章

相关标签