Skip to content

Instantly share code, notes, and snippets.

@ricardocanelas
Created July 16, 2020 16:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ricardocanelas/ac0a219706d02e6d41b399cccdec1ae0 to your computer and use it in GitHub Desktop.
Save ricardocanelas/ac0a219706d02e6d41b399cccdec1ae0 to your computer and use it in GitHub Desktop.
Embed Video (youtube & vimeo)
function stripParameters(str) {
// Split parameters or split folder separator
if (str.indexOf('?') > -1) {
return str.split('?')[0]
} else if (str.indexOf('/') > -1) {
return str.split('/')[0]
}
return str
}
function youtube(str) {
// shortcode
const shortcode = /youtube:\/\/|https?:\/\/youtu\.be\/|http:\/\/y2u\.be\//g
if (shortcode.test(str)) {
const shortcodeid = str.split(shortcode)[1]
return { id: stripParameters(shortcodeid) }
}
// /v/ or /vi/
const inlinev = /\/v\/|\/vi\//g
if (inlinev.test(str)) {
const inlineid = str.split(inlinev)[1]
return { id: stripParameters(inlineid) }
}
// v= or vi=
const parameterv = /v=|vi=/g
if (parameterv.test(str)) {
const arr = str.split(parameterv)
return { id: arr[1].split('&')[0] }
}
// v= or vi=
const parameterwebp = /\/an_webp\//g
if (parameterwebp.test(str)) {
const webp = str.split(parameterwebp)[1]
return { id: stripParameters(webp) }
}
// embed
const embedreg = /\/embed\//g
if (embedreg.test(str)) {
const embedid = str.split(embedreg)[1]
return { id: stripParameters(embedid) }
}
// ignore /user/username pattern
const usernamereg = /\/user\/([a-zA-Z0-9]*)$/g
if (usernamereg.test(str)) {
return undefined
}
// user
const userreg = /\/user\/(?!.*videos)/g
if (userreg.test(str)) {
const elements = str.split('/')
return { id: stripParameters(elements.pop()) }
}
// attribution_link
const attrreg = /\/attribution_link\?.*v%3D([^%&]*)(%26|&|$)/
if (attrreg.test(str)) {
return { id: str.match(attrreg)[1] }
}
// list
const listreg = /list=([0-9a-z_-]{1,})/i
if (listreg.test(str)) {
return { list: str.match(listreg)[1] }
}
return undefined
}
function getMetadata(str) {
// remove surrounding whitespaces or linefeeds
str = str.trim()
// remove the '-nocookie' flag from youtube urls
str = str.replace('-nocookie', '')
// remove any leading `www.`
str = str.replace('/www.', '/')
let metadata = {}
if (/youtube|youtu\.be|y2u\.be|i.ytimg\./.test(str)) {
metadata = {
url: str,
service: 'youtube',
...youtube(str),
}
}
if (/vimeo/.test(str)) {
metadata = {
url: str,
service: 'vimeo',
...vimeo(str),
}
}
return metadata
}
function vimeo(str) {
if (str.indexOf('#') > -1) {
str = str.split('#')[0]
}
if (str.indexOf('?') > -1 && str.indexOf('clip_id=') === -1) {
str = str.split('?')[0]
}
let id
let arr
const vimeoPipe = [
'https?://vimeo.com/[0-9]+$',
'https?://player.vimeo.com/video/[0-9]+$',
'https?://vimeo.com/channels',
'groups',
'album',
].join('|')
const vimeoRegex = new RegExp(vimeoPipe, 'gim')
if (vimeoRegex.test(str)) {
arr = str.split('/')
if (arr && arr.length) {
id = arr.pop()
}
} else if (/clip_id=/gim.test(str)) {
arr = str.split('clip_id=')
if (arr && arr.length) {
id = arr[1].split('&')[0]
}
}
return { id }
}
export function getEmbedURL(url, prefix = null) {
const qstring = prefix ? '?' + prefix : ''
const metadata = getMetadata(url)
if (metadata.service) {
if (metadata.service === 'youtube' && metadata.id) {
return `https://www.youtube.com/embed/${metadata.id}${qstring}`
}
if (metadata.service === 'youtube' && metadata.list) {
return `https://www.youtube.com/embed/videoseries?list=${metadata.list}${prefix ? '&' + prefix : ''}`
}
if (metadata.service === 'vimeo') {
return `https://player.vimeo.com/video/${metadata.id}${qstring}`
}
}
return ''
}
import { getEmbedURL } from './embedVideo'
it('should return vimeo url properly', () => {
const urls = [
'https://vimeo.com/83651159',
'https://player.vimeo.com/video/83651159',
'https://vimeo.com/album/4298998',
]
expect(getEmbedURL(urls[0])).toBe('https://player.vimeo.com/video/83651159')
expect(getEmbedURL(urls[1])).toBe('https://player.vimeo.com/video/83651159')
expect(getEmbedURL(urls[1])).toBe('https://player.vimeo.com/video/83651159')
})
it('should return youtube url properly', () => {
const urls = [
'https://www.youtube.com/watch?v=dY_3ggKg0Bc',
'https://www.youtube.com/embed/dY_3ggKg0Bc?autoplay=1',
'https://www.youtube.com/embed/UuGrBhK2c7U',
'https://youtu.be/F6nwZUkBeas',
'https://youtu.be/Wx9vPv-T51I?list=PLy7FC6EHSvO3X_kCEj2hookdcV3pXxzXU',
'https://m.youtube.com/watch?v=R-Iak3Wvh9c&ebc=ANyPxKrTzEXKD6LhC0WiXHCrqFpKWawRi-ZSpZcsZhH_q7e1NQhMF8-DP8D0bzGmuZ5vLJb8x11qOOTV1LA957QNASIZ3VN-8g',
'https://www.youtube.com/watch?v=GmP2eI5VFVM&list=RDMMGmP2eI5VFVM&start_radio=1',
'https://www.youtube.com/playlist?list=PLjsOUjB_EBTEx0blZta0BmUeaIuE8rpR2',
]
expect(getEmbedURL(urls[0])).toBe('https://www.youtube.com/embed/dY_3ggKg0Bc')
expect(getEmbedURL(urls[1])).toBe('https://www.youtube.com/embed/dY_3ggKg0Bc')
expect(getEmbedURL(urls[2])).toBe('https://www.youtube.com/embed/UuGrBhK2c7U')
expect(getEmbedURL(urls[3])).toBe('https://www.youtube.com/embed/F6nwZUkBeas')
expect(getEmbedURL(urls[4])).toBe('https://www.youtube.com/embed/Wx9vPv-T51I')
expect(getEmbedURL(urls[5])).toBe('https://www.youtube.com/embed/R-Iak3Wvh9c')
expect(getEmbedURL(urls[6])).toBe('https://www.youtube.com/embed/GmP2eI5VFVM')
expect(getEmbedURL(urls[7])).toBe('https://www.youtube.com/embed/videoseries?list=PLjsOUjB_EBTEx0blZta0BmUeaIuE8rpR2')
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment