Audio metadata

This commit is contained in:
DC
2016-03-22 03:37:27 -07:00
parent fc425e4221
commit fcf0e0d2fb
4 changed files with 82 additions and 4 deletions

View File

@@ -22,6 +22,7 @@
"hyperx": "^2.0.2",
"main-loop": "^3.2.0",
"mkdirp": "^0.5.1",
"musicmetadata": "^2.0.2",
"network-address": "^1.1.0",
"prettier-bytes": "^1.0.1",
"upload-element": "^1.0.1",
@@ -30,7 +31,6 @@
"winreg": "^1.0.1"
},
"devDependencies": {
"appdmg": "^0.3.6",
"electron-osx-sign": "^0.3.0",
"electron-packager": "^5.0.0",
"electron-prebuilt": "0.37.2",
@@ -40,6 +40,9 @@
"rimraf": "^2.5.2",
"standard": "^6.0.5"
},
"optionalDependencies": {
"appdmg": "^0.3.6"
},
"homepage": "https://webtorrent.io",
"keywords": [
"electron",

View File

@@ -730,6 +730,34 @@ body.drag .torrent-placeholder span {
font-weight: bold;
}
/*
* AUDIO DETAILS
*/
.audio-metadata {
width: 500px;
max-width: 100%;
white-space: nowrap;
text-overflow: ellipsis;
align-self: center;
margin: 0 auto;
font-weight: bold;
font-size: 24px;
line-height: 2;
}
.audio-metadata .audio-title {
font-size: 32px;
}
.audio-metadata label {
display:inline-block;
width: 100px;
text-align: right;
font-weight: normal;
margin-right: 25px;
}
/*
* ERRORS
*/

View File

@@ -8,6 +8,7 @@ var EventEmitter = require('events')
var fs = require('fs')
var mainLoop = require('main-loop')
var mkdirp = require('mkdirp')
var musicmetadata = require('musicmetadata')
var networkAddress = require('network-address')
var path = require('path')
var remote = require('remote')
@@ -609,7 +610,17 @@ function startServerFromReadyTorrent (torrent, index, cb) {
state.playing.infoHash = torrent.infoHash
state.playing.fileIndex = index
state.playing.type = TorrentPlayer.isVideo(file) ? 'video' : 'audio'
state.playing.audioInfo = null
// if it's audio, parse out the metadata (artist, title, etc)
musicmetadata(file.createReadStream(), function (err, info) {
if (err) return
console.log('Got audio metadata for %s: %v', file.name, info)
state.playing.audioInfo = info
update()
})
// either way, start a streaming torrent-to-http server
var server = torrent.createServer()
server.listen(0, function () {
var port = server.address().port

View File

@@ -21,6 +21,8 @@ function Player (state, dispatch) {
}
function renderMedia (state, dispatch) {
if (!state.server) return
// Unfortunately, play/pause can't be done just by modifying HTML.
// Instead, grab the DOM node and play/pause it if necessary
var mediaType = state.playing.type /* 'audio' or 'video' */
@@ -57,8 +59,9 @@ function renderMedia (state, dispatch) {
// Show the media.
// Video fills the window, centered with black bars if necessary
// Audio gets a static poster image and a summary of the file metadata.
var isAudio = mediaType === 'audio'
var style = {
backgroundImage: mediaType === 'audio' ? cssBackgroundImagePoster(state) : ''
backgroundImage: isAudio ? cssBackgroundImagePoster(state) : ''
}
return hx`
<div
@@ -66,6 +69,7 @@ function renderMedia (state, dispatch) {
style=${style}
onmousemove=${() => dispatch('mediaMouseMoved')}>
${mediaTag}
${renderAudioMetadata(state)}
</div>
`
@@ -86,6 +90,34 @@ function renderMedia (state, dispatch) {
}
}
function renderAudioMetadata (state) {
if (!state.playing.audioInfo) return
var info = state.playing.audioInfo
// Get audio track info
var title = info.title
if (!title) {
var torrentSummary = getPlayingTorrentSummary(state)
title = torrentSummary.files[state.playing.fileIndex].name
}
var artist = info.artist && info.artist[0]
var album = info.album
if (album && info.year && !album.includes(info.year)) {
album += ' (' + info.year + ')'
}
var track
if (info.track && info.track.no && info.track.of) {
track = info.track.no + ' of ' + info.track.of
}
// Show a small info box in the middle of the screen
var elems = [hx`<div class='audio-title'><label></label>${title}</div>`]
if (artist) elems.push(hx`<div class='audio-artist'><label>Artist</label>${artist}</div>`)
if (album) elems.push(hx`<div class='audio-album'><label>Album</label>${album}</div>`)
if (track) elems.push(hx`<div class='audio-track'><label>Track</label>${track}</div>`)
return hx`<div class='audio-metadata'>${elems}</div>`
}
function renderCastScreen (state, dispatch) {
var isChromecast = state.playing.location.startsWith('chromecast')
var isAirplay = state.playing.location.startsWith('airplay')
@@ -112,8 +144,7 @@ function renderCastScreen (state, dispatch) {
// Returns the CSS background-image string for a poster image + dark vignette
function cssBackgroundImagePoster (state) {
var infoHash = state.playing.infoHash
var torrentSummary = state.saved.torrents.find((x) => x.infoHash === infoHash)
var torrentSummary = getPlayingTorrentSummary(state)
if (!torrentSummary || !torrentSummary.posterURL) return ''
var cleanURL = torrentSummary.posterURL.replace(/\\/g, '/')
return 'radial-gradient(circle at center, ' +
@@ -121,6 +152,11 @@ function cssBackgroundImagePoster (state) {
`, url(${cleanURL})`
}
function getPlayingTorrentSummary (state) {
var infoHash = state.playing.infoHash
return state.saved.torrents.find((x) => x.infoHash === infoHash)
}
function renderPlayerControls (state, dispatch) {
var positionPercent = 100 * state.playing.currentTime / state.playing.duration
var playbackCursorStyle = { left: 'calc(' + positionPercent + '% - 8px)' }