Skip to content

Commit

Permalink
Add audio support
Browse files Browse the repository at this point in the history
  • Loading branch information
Kikobeats committed Sep 1, 2018
1 parent 7f54518 commit 7d5ad34
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 50 deletions.
98 changes: 54 additions & 44 deletions packages/metascraper-media-provider/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,84 +8,94 @@ const {
get,
chain,
find,
negate,
isString
} = require('lodash')
const { isUrl, titleize } = require('@metascraper/helpers')
const path = require('path')

const getVideoInfo = require('./get-video-info')

const isMp4 = video =>
eq(get(video, 'ext'), 'mp4') ||
path.extname(get(video, 'url')).startsWith('.mp4')
const isHttp = video => eq(get(video, 'protocol'), 'http')
const isHttps = video => eq(get(video, 'protocol'), 'https')
const hasAudio = video => has(video, 'abr')
const isMIME = ext => item =>
eq(get(item, 'ext'), ext) ||
path.extname(get(item, 'url')).startsWith(`.${ext}`)

const getVideoUrls = (videos, filters = []) => {
const isMp4 = isMIME('mp4')
const isMp3 = isMIME('mp3')
const isM4a = isMIME('m4a')
const isAac = isMIME('aac')

const isHttp = item => eq(get(item, 'protocol'), 'http')
const isHttps = item => eq(get(item, 'protocol'), 'https')
const hasAudio = item => has(item, 'abr')
const hasVideo = item => has(item, 'tbr')

const getFormatUrls = orderBy => (videos, filters = []) => {
const urls = chain(videos)
.filter(overEvery(filters))
.orderBy('tbr', 'asc')
.orderBy(orderBy, 'asc')
.map('url')
.filter(isUrl)
.value()

return isEmpty(urls) ? false : urls
}

const getVideoProvider = async ({ url }) => {
const { formats } = await getVideoInfo(url)
const getVideoUrls = getFormatUrls('tbr')
const getAudioUrls = getFormatUrls('abr')

const videoUrl =
getVideoUrls(formats, [isMp4, isHttps, hasAudio]) ||
getVideoUrls(formats, [isMp4, isHttp, hasAudio]) ||
getVideoUrls(formats, [isMp4, isHttps]) ||
getVideoUrls(formats, [isMp4])
const getVideo = ({ formats }) =>
getVideoUrls(formats, [hasAudio, isMp4, isHttps]) ||
getVideoUrls(formats, [hasAudio, isMp4, isHttp]) ||
getVideoUrls(formats, [isMp4, isHttps]) ||
getVideoUrls(formats, [isMp4, isHttp]) ||
getVideoUrls(formats, [isMp4])

return isUrl(videoUrl) && videoUrl
}
const getAudio = ({ formats }) =>
getAudioUrls(formats, [negate(hasVideo), isMp3, isHttps]) ||
getAudioUrls(formats, [negate(hasVideo), isAac, isHttps]) ||
getAudioUrls(formats, [negate(hasVideo), isM4a, isHttps]) ||
getAudioUrls(formats, [negate(hasVideo), isMp3, isHttp]) ||
getAudioUrls(formats, [negate(hasVideo), isAac, isHttp]) ||
getAudioUrls(formats, [negate(hasVideo), isM4a, isHttp]) ||
getAudioUrls(formats, [negate(hasVideo), isMp3]) ||
getAudioUrls(formats, [negate(hasVideo), isAac]) ||
getAudioUrls(formats, [negate(hasVideo), isM4a])

/**
* Get the Author of the video.
*/
const getVideoAuthor = async ({ url }) => {
const { uploader, creator, uploader_id: uploaderId } = await getVideoInfo(url)
const getAuthor = ({ uploader, creator, uploader_id: uploaderId }) => {
const author = find(
[creator, uploader, uploaderId],
str => isString(str) && !isUrl(str, { relative: false })
)
return author && titleize(author, { removeBy: true })
}

const getVideoPublisher = async ({ url }) => {
const { extractor_key: extractorKey } = await getVideoInfo(url)
return isString(extractorKey) && extractorKey
}
const getPublisher = ({ extractor_key: extractorKey }) =>
isString(extractorKey) && extractorKey

const getVideoTitle = async ({ url }) => {
const { title: mainTitle, alt_title: secondaryTitle } = await getVideoInfo(
url
)
const getTitle = ({ title: mainTitle, alt_title: secondaryTitle }) => {
const title = find([mainTitle, secondaryTitle], isString)
return title && titleize(title)
}

const getVideoDate = async ({ url }) => {
const { timestamp } = await getVideoInfo(url)
return timestamp && new Date(timestamp * 1000).toISOString()
}
const getDate = ({ timestamp }) =>
timestamp && new Date(timestamp * 1000).toISOString()

module.exports = () => {
return {
video: getVideoProvider,
author: getVideoAuthor,
publisher: getVideoPublisher,
title: getVideoTitle,
date: getVideoDate
video: async ({ url }) => getVideo(await getVideoInfo(url)),
audio: async ({ url }) => getAudio(await getVideoInfo(url)),
author: async ({ url }) => getAuthor(await getVideoInfo(url)),
publisher: async ({ url }) => getPublisher(await getVideoInfo(url)),
title: async ({ url }) => getTitle(await getVideoInfo(url)),
date: async ({ url }) => getDate(await getVideoInfo(url))
}
}

module.exports.getVideoUrls = getVideoUrls
module.exports.isMp4 = isMp4
module.exports.isHttp = isHttp
module.exports.isHttps = isHttps
module.exports.hasAudio = hasAudio
module.exports.getFormatUrls = getFormatUrls
module.exports.getVideo = getVideo
module.exports.getAudio = getAudio
module.exports.getAuthor = getAuthor
module.exports.getPublisher = getPublisher
module.exports.getTitle = getTitle
module.exports.getDate = getDate
9 changes: 3 additions & 6 deletions packages/metascraper-media-provider/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,13 @@ const metascraper = require('metascraper')([

const readFile = promisify(fs.readFile)

const { getVideoUrls, isMp4 } = require('metascraper-media-provider')
const { getVideo } = require('metascraper-media-provider')

const output = require('./fixtures/youtube-dl.json')

describe('metascraper-media-provider', () => {
describe('.getVideoUrls', () => {
it('filter by mp4', () => {
const videoUrls = getVideoUrls(output.formats, [isMp4])
snapshot(videoUrls)
})
it('.getVideo', () => {
snapshot(getVideo(output.formats))
})
describe('provider', () => {
it('vimeo', async () => {
Expand Down

0 comments on commit 7d5ad34

Please sign in to comment.