Audio metadata
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)' }
|
||||
|
||||
Reference in New Issue
Block a user