Skip to content

Commit

Permalink
Release v0.1.0
Browse files Browse the repository at this point in the history
Breaking changes:

- Changed the export from `default` to a named `YouTube` export
- Renamed the `videoCode` prop to `videoId` to match what YouTube uses in their docs

New:

- Added an `embedParams` prop to expose all the settings from the [YouTube Iframe Player API](https://developers.google.com/youtube/player_parameters#Parameters)
  - Default settings are {autoplay: 1, modestbranding: 1}
- Added a `thumbNailRes` prop to let you choose the thumbnail size/quality which is used
  - Default setting is 'standard' (which is bigger than 'high' - go figure)
  - Not all videos have all thumbnail sizes (especially older ones), so you may have to tweak this on a per-video basis
  • Loading branch information
insin committed Jul 19, 2023
1 parent cfd09d4 commit e263e99
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 38 deletions.
33 changes: 24 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,38 @@ Lazily embed YouTube videos with a [static placeholder using the `<iframe>` `src
npm i astro-lazy-youtube-embed
```

## Example
## Usage

This component uses a `default` export, so you can import it as whichever name you prefer:
Use `embedParams` to pass [YouTube IFrame Player API parameters](https://developers.google.com/youtube/player_parameters#Parameters) for the embed, e.g. to set start & stop times to play a particular section when clicked.

Use `thumbnailRes` to control the resolution of the thumbnail used for the placeholder.

```astro
---
import YouTubeVideo from 'astro-lazy-youtube-embed'
import {YouTube} from 'astro-lazy-youtube-embed'
---
<YouTubeVideo videoCode="FfTT7mxGw8I" title="Just Curious - Limmy's Homemade Show"/>
<YouTube
title="Just Curious - Limmy's Homemade Show"
videoId="FfTT7mxGw8I"
/>
<div class="my-8">Configure the embed features and thumbnail size:</div>
<YouTube
embedParams={{start: 19, end: 22}}
thumbnailRes="maxres"
title="Frimmerang"
videoId="xptCWoB_VCE"
/>
<div class="my-8">Provide your own class for additional styling:</div>
<div class="my-8">Pass other HTML attributes for the <code>&lt;iframe&gt;</code>:</div>
<YouTubeVideo
class="rounded"
videoCode="L0C5nyOVTzc"
<YouTube
class="rounded-2xl"
id="techno"
title="Limmy Teaches Techno - Limmy's Homemade Show"
videoId="L0C5nyOVTzc"
/>
```

![Rendered version of the above example code](/example.jpg)
![Rendered version of the above example code](./example.jpg)
77 changes: 77 additions & 0 deletions YouTube.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
---
interface Props extends astroHTML.JSX.HTMLAttributes {
embedParams?: EmbedParams
thumbnailRes?: ThumbnailRes
title: string
videoId: string
}
interface EmbedParams {
autoplay?: ToggleParam
cc_lang_pref?: string
cc_load_policy?: ToggleParam
color?: 'red' | 'white'
controls?: ToggleParam
disablekb?: ToggleParam
enablejsapi?: ToggleParam
end?: number
fs?: ToggleParam
hl?: string
iv_load_policy?: 1 | '1' | 3 | '3'
list?: string
listType?: 'playlist' | 'user_uploads'
loop?: ToggleParam
modestbranding?: ToggleParam
origin?: string
playlist?: string
playslinline?: ToggleParam
rel?: ToggleParam
start?: number
widget_referrer?: string
}
type ToggleParam = 0 | '0' | 1 | '1'
type ThumbnailRes = 120 | '120' | 'default' | 320 | '320' | 'medium' | 480 | '480' | 'high' | 640 | '640' | 'standard' | 1280 | '1280' | 'maxres'
const QUALITY_PREFIXES = {
120: '',
default: '',
320: 'mq',
medium: 'mq',
480: 'hq',
high: 'hq',
640: 'sd',
standard: 'sd',
1280: 'maxres',
maxres: 'maxres',
}
let {
embedParams,
thumbnailRes = 'standard',
title,
videoId,
...attrs
} = Astro.props as Props
let params: EmbedParams = {...{autoplay: 1, modestbranding: 1}, ...embedParams}
let thumbnailUrl = `https://img.youtube.com/vi/${videoId}/${QUALITY_PREFIXES[thumbnailRes]}default.jpg`
let embedQuery = Object.keys(params).map(key => `${key}=${params[key]}`).join('&')
let embedUrl = `https://www.youtube.com/embed${videoId ? `/${videoId}` : ''}${embedQuery ? `?${embedQuery}` : ''}`
let playButtonSvg = `<svg height="100%" version="1.1" viewBox="0 0 68 48" width="100%"><path d="M66.52,7.74c-0.78-2.93-2.49-5.41-5.42-6.19C55.79,.13,34,0,34,0S12.21,.13,6.9,1.55 C3.97,2.33,2.27,4.81,1.48,7.74C0.06,13.05,0,24,0,24s0.06,10.95,1.48,16.26c0.78,2.93,2.49,5.41,5.42,6.19 C12.21,47.87,34,48,34,48s21.79-0.13,27.1-1.55c2.93-0.78,4.64-3.26,5.42-6.19C67.94,34.95,68,24,68,24S67.94,13.05,66.52,7.74z" fill="#f00"></path><path d="M 45,24 27,14 27,34" fill="#fff"></path></svg>`
let gradientStyle = `.gradient{width:100%;height:49px;padding-bottom:50px;position:absolute;top:0;background-repeat:repeat-x;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAADGCAYAAAAT+OqFAAAAdklEQVQoz42QQQ7AIAgEF/T/D+kbq/RWAlnQyyazA4aoAB4FsBSA/bFjuF1EOL7VbrIrBuusmrt4ZZORfb6ehbWdnRHEIiITaEUKa5EJqUakRSaEYBJSCY2dEstQY7AuxahwXFrvZmWl2rh4JZ07z9dLtesfNj5q0FU3A5ObbwAAAABJRU5ErkJggg==);pointer-events:none;}`
let style = `<style>*{padding:0;margin:0;overflow:hidden}html,body{height:100%}img{position:absolute;width:100%;top:0;bottom:0;margin:auto}.button{position:absolute;left:50%;top:50%;width:68px;height:48px;margin-left:-34px;margin-top:-24px;}.top{position:absolute;top:18px;left:18px;right:18px;display:flex;flex-wrap:nowrap}.title{color:#fff;font-size:18px;white-space:nowrap;word-wrap:normal;text-shadow:0 0 2px rgba(0,0,0,.5);font-family:"YouTube Noto",Roboto,Arial,Helvetica,sans-serif;line-height:1.3;text-overflow:ellipsis;overflow:hidden;}${gradientStyle}</style>`
let srcdoc = `${style}<a href="${embedUrl}"><img src="${thumbnailUrl}" alt="${title}"><div class="gradient"></div><div class="top"><div class="title">${title}</div></div><div class="button">${playButtonSvg}</div></a>`
---
<iframe
allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen
frameborder="0"
style="width: 100%; aspect-ratio: 16/9;"
{...attrs}
src={embedUrl}
srcdoc={srcdoc}
title={title}
/>
22 changes: 0 additions & 22 deletions YouTubeVideo.astro

This file was deleted.

Binary file modified example.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 0 additions & 1 deletion index.js

This file was deleted.

1 change: 1 addition & 0 deletions index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {default as YouTube} from './YouTube.astro'
12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
{
"name": "astro-lazy-youtube-embed",
"version": "0.0.2",
"version": "0.1.0",
"description": "Embed YouTube videos with a static placeholder which only embeds when you click",
"type": "module",
"license": "MIT",
"author": "Jonny Buchanan <jonathan.buchanan@gmail.com>",
"exports": {
".": "./index.js"
".": "./index.ts"
},
"files": [
"index.js",
"index.ts",
"LICENSE",
"YouTubeVideo.astro"
"YouTube.astro"
],
"keywords": [
"astro",
"astro-component",
"lazy",
"youtube",
"embed"
"embeds",
"lazy"
],
"peerDependencies": {
"astro": "^1.0.0 || ^2.0.0-beta"
Expand Down

0 comments on commit e263e99

Please sign in to comment.