space-before-colon: 1
hex-length: 1
hex-notation: 0
- indentation: 1
+ indentation: 2
},
"license": "GPLv3",
"resolutions": {
- "videojs-dock/video.js": "^7",
+ "video.js": "^7",
"webtorrent/create-torrent/junk": "^1",
"simple-get": "^2.8.1"
},
"typescript": "2.7",
"uglifyjs-webpack-plugin": "^1.1.2",
"video.js": "^7.0.3",
+ "videojs-contextmenu": "^2.0.0",
+ "videojs-contextmenu-ui": "^4.0.0",
"videojs-dock": "^2.0.2",
"videojs-hotkeys": "^0.2.21",
"webpack": "^4.5.0",
import { ModalDirective } from 'ngx-bootstrap/modal'
import { VideoDetails } from '../../../shared/video/video-details.model'
+import { buildVideoEmbed } from '../../../../assets/player/utils'
@Component({
selector: 'my-video-share',
}
getVideoIframeCode () {
- return '<iframe width="560" height="315" ' +
- 'src="' + this.video.embedUrl + '" ' +
- 'frameborder="0" allowfullscreen>' +
- '</iframe>'
+ return buildVideoEmbed(this.video.embedUrl)
}
getVideoUrl () {
inactivityTimeout: 2500,
videoFiles: this.video.files,
playerElement: this.playerElement,
+ videoEmbedUrl: this.video.embedUrl,
videoViewUrl: this.videoService.getVideoViewUrl(this.video.uuid),
videoDuration: this.video.duration,
enableHotkeys: true,
import { VideoJSComponentInterface, videojsUntyped } from './peertube-videojs-typings'
+import { buildVideoLink } from './utils'
const Button: VideoJSComponentInterface = videojsUntyped.getComponent('Button')
class PeerTubeLinkButton extends Button {
+ constructor (player: videojs.Player, options) {
+ super(player, options)
+ }
+
createEl () {
return this.buildElement()
}
updateHref () {
- const currentTime = Math.floor(this.player().currentTime())
- this.el().setAttribute('href', this.buildHref(currentTime))
+ this.el().setAttribute('href', buildVideoLink(this.player().currentTime()))
}
handleClick () {
private buildElement () {
const el = videojsUntyped.dom.createEl('a', {
- href: this.buildHref(),
+ href: buildVideoLink(),
innerHTML: 'PeerTube',
title: 'Go to the video page',
className: 'vjs-peertube-link',
return el
}
-
- private buildHref (time?: number) {
- let href = window.location.href.replace('embed', 'watch')
- if (time) {
- if (window.location.search) href += '&start=' + time
- else href += '?start=' + time
- }
-
- return href
- }
}
Button.registerComponent('PeerTubeLinkButton', PeerTubeLinkButton)
import 'videojs-hotkeys'
import 'videojs-dock'
+import 'videojs-contextmenu'
+import 'videojs-contextmenu-ui'
import './peertube-link-button'
import './resolution-menu-button'
import './settings-menu-button'
import './webtorrent-info-button'
import './peertube-videojs-plugin'
import { videojsUntyped } from './peertube-videojs-typings'
+import { buildVideoEmbed, buildVideoLink, copyToClipboard } from './utils'
// Change 'Playback Rate' to 'Speed' (smaller for our settings menu)
videojsUntyped.getComponent('PlaybackRateMenuButton').prototype.controlText_ = 'Speed'
autoplay: boolean,
playerElement: HTMLVideoElement,
videoViewUrl: string,
+ videoEmbedUrl: string,
videoDuration: number,
videoFiles: VideoFile[],
enableHotkeys: boolean,
videoViewUrl: options.videoViewUrl,
videoDuration: options.videoDuration,
startTime: options.startTime
+ },
+ contextmenuUI: {
+ content: [
+ {
+ label: 'Copy the video URL',
+ listener: function () {
+ copyToClipboard(buildVideoLink())
+ }
+ },
+ {
+ label: 'Copy the video URL at the current time',
+ listener: function () {
+ const player = this
+ copyToClipboard(buildVideoLink(player.currentTime()))
+ }
+ },
+ {
+ label: 'Copy embed code',
+ listener: () => {
+ copyToClipboard(buildVideoEmbed(options.videoEmbedUrl))
+ }
+ }
+ ]
}
},
controlBar: {
this.trigger('autoResolutionUpdate')
}
+ getCurrentVideoFile () {
+ return this.currentVideoFile
+ }
+
private tryToPlay (done?: Function) {
if (!done) done = function () { /* empty */ }
return /iPhone|iPad|iPod|Android/i.test(navigator.userAgent)
}
+function buildVideoLink (time?: number) {
+ let href = window.location.href.replace('/embed/', '/watch/')
+ if (time) {
+ const timeInt = Math.floor(time)
+
+ if (window.location.search) href += '&start=' + timeInt
+ else href += '?start=' + timeInt
+ }
+
+ return href
+}
+
+function buildVideoEmbed (embedUrl: string) {
+ return '<iframe width="560" height="315" ' +
+ 'src="' + embedUrl + '" ' +
+ 'frameborder="0" allowfullscreen>' +
+ '</iframe>'
+}
+
+function copyToClipboard (text: string) {
+ const el = document.createElement('textarea')
+ el.value = text
+ el.setAttribute('readonly', '')
+ el.style.position = 'absolute'
+ el.style.left = '-9999px'
+ document.body.appendChild(el)
+ el.select()
+ document.execCommand('copy')
+ document.body.removeChild(el)
+}
+
export {
toTitleCase,
+ buildVideoLink,
getStoredVolume,
saveVolumeInStore,
saveAverageBandwidth,
getAverageBandwidth,
saveMuteInStore,
+ buildVideoEmbed,
getStoredMute,
+ copyToClipboard,
isMobile,
bytes
}
return fallbackToMediaSource()
})
- preparedElem.addEventListener('canplay', onLoadStart)
+ preparedElem.addEventListener('loadstart', onLoadStart)
return videostream(file, preparedElem)
}
return callback(err)
})
- preparedElem.addEventListener('canplay', onLoadStart)
+ preparedElem.addEventListener('loadstart', onLoadStart)
const wrapper = new MediaElementWrapper(preparedElem)
const writable = wrapper.createWriteStream(codecs)
}
function onLoadStart () {
- preparedElem.removeEventListener('canplay', onLoadStart)
+ preparedElem.removeEventListener('loadstart', onLoadStart)
if (opts.autoplay) preparedElem.play()
callback(null, renderer)
$setting-transition-duration: 0.15s;
$setting-transition-easing: ease-out;
+$context-menu-width: 350px;
+
.video-js.vjs-peertube-skin {
font-size: $font-size;
color: $primary-foreground-color;
}
}
}
+}
+
+/* Sass for videojs-contextmenu-ui */
+
+.video-js .vjs-contextmenu-ui-menu {
+ position: absolute;
+ background-color: rgba(0, 0, 0, 0.5);
+ padding: 5px 0;
+ width: $context-menu-width;
+
+ .vjs-menu-content {
+ opacity: $primary-foreground-opacity;
+ color: $primary-foreground-color;
+ font-size: $font-size !important;
+ font-weight: $font-semibold;
+ }
+
+ .vjs-menu-item {
+ cursor: pointer;
+ font-size: 1em;
+ padding: 8px 16px;
+ text-align: left;
+ text-transform: none;
+
+ &:hover {
+ background-color: rgba(255, 255, 255, 0.2);
+ }
+ }
}
\ No newline at end of file
const videojsOptions = getVideojsOptions({
autoplay,
inactivityTimeout: 1500,
+ videoEmbedUrl: window.location.origin + videoInfo.embedPath,
videoViewUrl: getVideoUrl(videoId) + '/views',
playerElement: videoElement,
videoFiles: videoInfo.files,
videojs-vtt.js "0.14.1"
xhr "2.4.0"
+videojs-contextmenu-ui@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/videojs-contextmenu-ui/-/videojs-contextmenu-ui-4.0.0.tgz#e7ffceacac95c5d2bc7f80db6f75675404de542a"
+ dependencies:
+ global "^4.3.2"
+ video.js "^5.19.2"
+ videojs-contextmenu "^2.0.0"
+
+videojs-contextmenu@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/videojs-contextmenu/-/videojs-contextmenu-2.0.0.tgz#7213c8c420ecd2904d26f19c21085f7ebf496e9e"
+ dependencies:
+ global "^4.3.2"
+ video.js "^5.19.2"
+
videojs-dock@^2.0.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/videojs-dock/-/videojs-dock-2.1.2.tgz#621c27c6f7dd131c541535300ac545377e515a0e"
"lint-staged": {
"*.{css,md}": "precise-commits",
"*.scss": [
- "sass-lint-auto-fix -c .sass-lint.yml --verbose",
+ "sass-lint -c .sass-lint.yml",
"git add"
]
},
"chai-json-schema": "^1.5.0",
"chai-xml": "^0.3.2",
"husky": "^1.0.0-rc.4",
- "libxmljs": "^0.18.9-pre0",
+ "libxmljs": "0.18.8",
"lint-staged": "^7.1.0",
"maildev": "^1.0.0-rc3",
"mocha": "^5.0.0",
"prettier": "1.13.2",
"prompt": "^1.0.0",
"sass-lint": "^1.12.1",
- "sass-lint-auto-fix": "^0.10.0",
"source-map-support": "^0.5.0",
"spectacle-docs": "^1.0.2",
"supertest": "^3.0.0",
version "1.5.1"
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c"
-ajv@^4.7.0, ajv@^4.9.1:
+ajv@^4.7.0:
version "4.11.8"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536"
dependencies:
nan "^2.9.2"
node-pre-gyp "^0.10.0"
-fstream-ignore@^1.0.5:
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105"
- dependencies:
- fstream "^1.0.0"
- inherits "2"
- minimatch "^3.0.0"
-
-fstream@^1.0.0, fstream@^1.0.10, fstream@^1.0.2:
+fstream@^1.0.0, fstream@^1.0.2:
version "1.0.11"
resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171"
dependencies:
optionalDependencies:
uglify-js "^2.6"
-har-schema@^1.0.5:
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e"
-
har-schema@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
is-my-json-valid "^2.12.4"
pinkie-promise "^2.0.0"
-har-validator@~4.2.1:
- version "4.2.1"
- resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a"
- dependencies:
- ajv "^4.9.1"
- har-schema "^1.0.5"
-
har-validator@~5.0.3:
version "5.0.3"
resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd"
dependencies:
traverse ">=0.2.4"
-hawk@3.1.3, hawk@~3.1.3:
+hawk@~3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4"
dependencies:
prelude-ls "~1.1.2"
type-check "~0.3.2"
-libxmljs@^0.18.9-pre0:
- version "0.18.9-pre0"
- resolved "https://registry.yarnpkg.com/libxmljs/-/libxmljs-0.18.9-pre0.tgz#2e607aae228d856777bab1205d54e0dcefe825ba"
+libxmljs@0.18.8:
+ version "0.18.8"
+ resolved "https://registry.yarnpkg.com/libxmljs/-/libxmljs-0.18.8.tgz#b0a07512a01290b6240600d6c2bc33a3c70976d6"
dependencies:
- bindings "~1.3.0"
+ bindings "^1.3.0"
nan "~2.10.0"
- node-pre-gyp "~0.6.37"
+ node-pre-gyp "^0.9.1"
lint-staged@^7.1.0:
version "7.1.2"
lru-cache "2"
sigmund "~1.0.0"
-"minimatch@2 || 3", minimatch@3.0.4, minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4, minimatch@~3.0.2:
+"minimatch@2 || 3", minimatch@3.0.4, minimatch@^3.0.2, minimatch@^3.0.4, minimatch@~3.0.2:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
dependencies:
tar "^2.0.0"
which "1"
-node-pre-gyp@0.9.1:
+node-pre-gyp@0.9.1, node-pre-gyp@^0.9.1:
version "0.9.1"
resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.9.1.tgz#f11c07516dd92f87199dbc7e1838eab7cd56c9e0"
dependencies:
semver "^5.3.0"
tar "^4"
-node-pre-gyp@~0.6.37:
- version "0.6.39"
- resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.39.tgz#c00e96860b23c0e1420ac7befc5044e1d78d8649"
- dependencies:
- detect-libc "^1.0.2"
- hawk "3.1.3"
- mkdirp "^0.5.1"
- nopt "^4.0.1"
- npmlog "^4.0.2"
- rc "^1.1.7"
- request "2.81.0"
- rimraf "^2.6.1"
- semver "^5.3.0"
- tar "^2.2.1"
- tar-pack "^3.4.0"
-
node-redis-scripty@0.0.5:
version "0.0.5"
resolved "https://registry.yarnpkg.com/node-redis-scripty/-/node-redis-scripty-0.0.5.tgz#4bf2d365ab6dab202cc08b7ac63f8f55aadc9625"
safe-buffer "^5.1.1"
which "^1.2.4"
-performance-now@^0.2.0:
- version "0.2.0"
- resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5"
-
performance-now@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
version "6.3.2"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.3.2.tgz#e75bd5f6e268122a2a0e0bda630b2550c166502c"
-qs@~6.4.0:
- version "6.4.0"
- resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233"
-
random-access-file@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/random-access-file/-/random-access-file-2.0.1.tgz#dc22de79270e9a84cb36a2419b759725930dcaeb"
tunnel-agent "^0.6.0"
uuid "^3.1.0"
-request@2.81.0:
- version "2.81.0"
- resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0"
- dependencies:
- aws-sign2 "~0.6.0"
- aws4 "^1.2.1"
- caseless "~0.12.0"
- combined-stream "~1.0.5"
- extend "~3.0.0"
- forever-agent "~0.6.1"
- form-data "~2.1.1"
- har-validator "~4.2.1"
- hawk "~3.1.3"
- http-signature "~1.1.0"
- is-typedarray "~1.0.0"
- isstream "~0.1.2"
- json-stringify-safe "~5.0.1"
- mime-types "~2.1.7"
- oauth-sign "~0.8.1"
- performance-now "^0.2.0"
- qs "~6.4.0"
- safe-buffer "^5.0.1"
- stringstream "~0.0.4"
- tough-cookie "~2.3.0"
- tunnel-agent "^0.6.0"
- uuid "^3.0.0"
-
request@~2.79.0:
version "2.79.0"
resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de"
dependencies:
align-text "^0.1.1"
-rimraf@2, rimraf@2.x.x, rimraf@^2.2.1, rimraf@^2.2.8, rimraf@^2.4.2, rimraf@^2.5.1, rimraf@^2.5.4, rimraf@^2.6.1:
+rimraf@2, rimraf@2.x.x, rimraf@^2.2.1, rimraf@^2.2.8, rimraf@^2.4.2, rimraf@^2.5.4, rimraf@^2.6.1:
version "2.6.2"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36"
dependencies:
scss-tokenizer "^0.2.3"
yargs "^7.0.0"
-sass-lint-auto-fix@^0.10.0:
- version "0.10.0"
- resolved "https://registry.yarnpkg.com/sass-lint-auto-fix/-/sass-lint-auto-fix-0.10.0.tgz#89fd3cfd29fae30ddb7bbefa488053553ef0f10e"
+sass-lint-auto-fix@^0.9.0:
+ version "0.9.2"
+ resolved "https://registry.yarnpkg.com/sass-lint-auto-fix/-/sass-lint-auto-fix-0.9.2.tgz#b8b6eb95644f7919dfea33d04c1fc19ae8f07a11"
dependencies:
chalk "^2.3.2"
commander "^2.15.1"
pump "^1.0.0"
tar-stream "^1.1.2"
-tar-pack@^3.4.0:
- version "3.4.1"
- resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.4.1.tgz#e1dbc03a9b9d3ba07e896ad027317eb679a10a1f"
- dependencies:
- debug "^2.2.0"
- fstream "^1.0.10"
- fstream-ignore "^1.0.5"
- once "^1.3.3"
- readable-stream "^2.1.4"
- rimraf "^2.5.1"
- tar "^2.2.1"
- uid-number "^0.0.6"
-
tar-stream@^1.1.2:
version "1.6.1"
resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.1.tgz#f84ef1696269d6223ca48f6e1eeede3f7e81f395"
to-buffer "^1.1.0"
xtend "^4.0.0"
-tar@^2.0.0, tar@^2.2.1:
+tar@^2.0.0:
version "2.2.1"
resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1"
dependencies:
version "1.0.2"
resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7"
-uid-number@^0.0.6:
- version "0.0.6"
- resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81"
-
uint64be@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/uint64be/-/uint64be-1.0.1.tgz#1f7154202f2a1b8af353871dda651bf34ce93e95"