@ormoshe/js-video-url-parser 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +195 -0
- package/dist/jsVideoUrlParser.js +1571 -0
- package/dist/jsVideoUrlParser.min.js +1 -0
- package/lib/base.d.ts +2 -0
- package/lib/base.js +3 -0
- package/lib/index.d.ts +17 -0
- package/lib/index.js +18 -0
- package/lib/provider/allocine.d.ts +13 -0
- package/lib/provider/allocine.js +36 -0
- package/lib/provider/base-provider.d.ts +13 -0
- package/lib/provider/canalplus.d.ts +13 -0
- package/lib/provider/canalplus.js +46 -0
- package/lib/provider/coub.d.ts +13 -0
- package/lib/provider/coub.js +54 -0
- package/lib/provider/dailymotion.d.ts +14 -0
- package/lib/provider/dailymotion.js +70 -0
- package/lib/provider/facebook.d.ts +14 -0
- package/lib/provider/facebook.js +78 -0
- package/lib/provider/loom.d.ts +13 -0
- package/lib/provider/loom.js +51 -0
- package/lib/provider/soundcloud.d.ts +16 -0
- package/lib/provider/soundcloud.js +125 -0
- package/lib/provider/teachertube.d.ts +14 -0
- package/lib/provider/teachertube.js +110 -0
- package/lib/provider/ted.d.ts +14 -0
- package/lib/provider/ted.js +96 -0
- package/lib/provider/tiktok.d.ts +14 -0
- package/lib/provider/tiktok.js +50 -0
- package/lib/provider/twitch.d.ts +15 -0
- package/lib/provider/twitch.js +150 -0
- package/lib/provider/vimeo.d.ts +14 -0
- package/lib/provider/vimeo.js +89 -0
- package/lib/provider/voomly.d.ts +14 -0
- package/lib/provider/voomly.js +46 -0
- package/lib/provider/wistia.d.ts +15 -0
- package/lib/provider/wistia.js +112 -0
- package/lib/provider/youku.d.ts +13 -0
- package/lib/provider/youku.js +83 -0
- package/lib/provider/youtube.d.ts +15 -0
- package/lib/provider/youtube.js +205 -0
- package/lib/testUrls.js +11 -0
- package/lib/urlParser.d.ts +23 -0
- package/lib/urlParser.js +81 -0
- package/lib/util.js +104 -0
- package/package.json +59 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
const {
|
|
2
|
+
combineParams,
|
|
3
|
+
getTime,
|
|
4
|
+
} = require('../util');
|
|
5
|
+
|
|
6
|
+
function SoundCloud() {
|
|
7
|
+
this.provider = 'soundcloud';
|
|
8
|
+
this.defaultFormat = 'long';
|
|
9
|
+
this.formats = {
|
|
10
|
+
long: this.createLongUrl,
|
|
11
|
+
embed: this.createEmbedUrl,
|
|
12
|
+
};
|
|
13
|
+
this.mediaTypes = {
|
|
14
|
+
TRACK: 'track',
|
|
15
|
+
PLAYLIST: 'playlist',
|
|
16
|
+
APITRACK: 'apitrack',
|
|
17
|
+
APIPLAYLIST: 'apiplaylist',
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
module.exports = SoundCloud;
|
|
22
|
+
|
|
23
|
+
SoundCloud.prototype.parseUrl = function(url, result) {
|
|
24
|
+
var match = url.match(
|
|
25
|
+
/(?:m\.)?soundcloud\.com\/(?:([\w-]+)\/(sets\/)?)([\w-]+)/i
|
|
26
|
+
);
|
|
27
|
+
if (!match) {
|
|
28
|
+
return result;
|
|
29
|
+
}
|
|
30
|
+
result.channel = match[1];
|
|
31
|
+
if (match[1] === 'playlists' || match[2]) { //playlist
|
|
32
|
+
result.list = match[3];
|
|
33
|
+
} else { //track
|
|
34
|
+
result.id = match[3];
|
|
35
|
+
}
|
|
36
|
+
return result;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
SoundCloud.prototype.parseParameters = function(params) {
|
|
40
|
+
if (params.t) {
|
|
41
|
+
params.start = getTime(params.t);
|
|
42
|
+
delete params.t;
|
|
43
|
+
}
|
|
44
|
+
return params;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
SoundCloud.prototype.parseMediaType = function(result) {
|
|
48
|
+
if (result.id) {
|
|
49
|
+
if (result.channel === 'tracks') {
|
|
50
|
+
delete result.channel;
|
|
51
|
+
delete result.params.url;
|
|
52
|
+
result.mediaType = this.mediaTypes.APITRACK;
|
|
53
|
+
} else {
|
|
54
|
+
result.mediaType = this.mediaTypes.TRACK;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (result.list) {
|
|
58
|
+
if (result.channel === 'playlists') {
|
|
59
|
+
delete result.channel;
|
|
60
|
+
delete result.params.url;
|
|
61
|
+
result.mediaType = this.mediaTypes.APIPLAYLIST;
|
|
62
|
+
} else {
|
|
63
|
+
result.mediaType = this.mediaTypes.PLAYLIST;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return result;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
SoundCloud.prototype.parse = function(url, params) {
|
|
70
|
+
var result = {};
|
|
71
|
+
result = this.parseUrl(url, result);
|
|
72
|
+
result.params = this.parseParameters(params);
|
|
73
|
+
result = this.parseMediaType(result);
|
|
74
|
+
if (!result.id && !result.list) {
|
|
75
|
+
return undefined;
|
|
76
|
+
}
|
|
77
|
+
return result;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
SoundCloud.prototype.createLongUrl = function(vi, params) {
|
|
81
|
+
var url = '';
|
|
82
|
+
var startTime = params.start;
|
|
83
|
+
delete params.start;
|
|
84
|
+
|
|
85
|
+
if (vi.mediaType === this.mediaTypes.TRACK && vi.id && vi.channel) {
|
|
86
|
+
url = 'https://soundcloud.com/' + vi.channel + '/' + vi.id;
|
|
87
|
+
}
|
|
88
|
+
else if (vi.mediaType === this.mediaTypes.PLAYLIST && vi.list && vi.channel) {
|
|
89
|
+
url = 'https://soundcloud.com/' + vi.channel + '/sets/' + vi.list;
|
|
90
|
+
}
|
|
91
|
+
else if (vi.mediaType === this.mediaTypes.APITRACK && vi.id) {
|
|
92
|
+
url = 'https://api.soundcloud.com/tracks/' + vi.id;
|
|
93
|
+
}
|
|
94
|
+
else if (vi.mediaType === this.mediaTypes.APIPLAYLIST && vi.list) {
|
|
95
|
+
url = 'https://api.soundcloud.com/playlists/' + vi.list;
|
|
96
|
+
} else {
|
|
97
|
+
return undefined;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
url += combineParams(params);
|
|
101
|
+
|
|
102
|
+
if (startTime) {
|
|
103
|
+
url += '#t=' + startTime;
|
|
104
|
+
}
|
|
105
|
+
return url;
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
SoundCloud.prototype.createEmbedUrl = function(vi, params) {
|
|
109
|
+
var url = 'https://w.soundcloud.com/player/';
|
|
110
|
+
delete params.start;
|
|
111
|
+
|
|
112
|
+
if (vi.mediaType === this.mediaTypes.APITRACK && vi.id) {
|
|
113
|
+
params.url = 'https%3A//api.soundcloud.com/tracks/' + vi.id;
|
|
114
|
+
}
|
|
115
|
+
else if (vi.mediaType === this.mediaTypes.APIPLAYLIST && vi.list) {
|
|
116
|
+
params.url = 'https%3A//api.soundcloud.com/playlists/' + vi.list;
|
|
117
|
+
} else {
|
|
118
|
+
return undefined;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
url += combineParams(params);
|
|
122
|
+
return url;
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
require('../base').bind(new SoundCloud());
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { VideoInfo } from '../urlParser';
|
|
2
|
+
|
|
3
|
+
export interface TeacherTubeUrlParameters {
|
|
4
|
+
[key: string]: any;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export type TeacherTubeMediaTypes = 'video' | 'audio' | 'document' | 'channel' | 'collection' | 'group';
|
|
8
|
+
|
|
9
|
+
export interface TeacherTubeVideoInfo extends VideoInfo<TeacherTubeUrlParameters, TeacherTubeMediaTypes> {
|
|
10
|
+
provider: 'teachertube';
|
|
11
|
+
list?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export type TeacherTubeParseResult = TeacherTubeVideoInfo | undefined;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
const {
|
|
2
|
+
combineParams,
|
|
3
|
+
} = require('../util');
|
|
4
|
+
|
|
5
|
+
function TeacherTube() {
|
|
6
|
+
this.provider = 'teachertube';
|
|
7
|
+
this.alternatives = [];
|
|
8
|
+
this.defaultFormat = 'long';
|
|
9
|
+
this.formats = {
|
|
10
|
+
long: this.createLongUrl,
|
|
11
|
+
embed: this.createEmbedUrl,
|
|
12
|
+
};
|
|
13
|
+
this.mediaTypes = {
|
|
14
|
+
VIDEO: 'video',
|
|
15
|
+
AUDIO: 'audio',
|
|
16
|
+
DOCUMENT: 'document',
|
|
17
|
+
CHANNEL: 'channel',
|
|
18
|
+
COLLECTION: 'collection',
|
|
19
|
+
GROUP: 'group',
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
module.exports = TeacherTube;
|
|
24
|
+
|
|
25
|
+
TeacherTube.prototype.parse = function(url, params) {
|
|
26
|
+
var result = {};
|
|
27
|
+
|
|
28
|
+
result.list = this.parsePlaylist(params);
|
|
29
|
+
result.params = params;
|
|
30
|
+
|
|
31
|
+
var match = url.match(
|
|
32
|
+
/\/(audio|video|document|user\/channel|collection|group)\/(?:[\w-]+-)?(\w+)/
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
if (!match) {
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
result.mediaType = this.parseMediaType(match[1]);
|
|
39
|
+
result.id = match[2];
|
|
40
|
+
|
|
41
|
+
return result;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
TeacherTube.prototype.parsePlaylist = function(params) {
|
|
45
|
+
if (params['playlist-id']) {
|
|
46
|
+
var list = params['playlist-id'];
|
|
47
|
+
delete params['playlist-id'];
|
|
48
|
+
return list;
|
|
49
|
+
}
|
|
50
|
+
return undefined;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
TeacherTube.prototype.parseMediaType = function(mediaTypeMatch) {
|
|
54
|
+
switch (mediaTypeMatch) {
|
|
55
|
+
case 'audio':
|
|
56
|
+
return this.mediaTypes.AUDIO;
|
|
57
|
+
case 'video':
|
|
58
|
+
return this.mediaTypes.VIDEO;
|
|
59
|
+
case 'document':
|
|
60
|
+
return this.mediaTypes.DOCUMENT;
|
|
61
|
+
case 'user/channel':
|
|
62
|
+
return this.mediaTypes.CHANNEL;
|
|
63
|
+
case 'collection':
|
|
64
|
+
return this.mediaTypes.COLLECTION;
|
|
65
|
+
case 'group':
|
|
66
|
+
return this.mediaTypes.GROUP;
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
TeacherTube.prototype.createLongUrl = function(vi, params) {
|
|
71
|
+
if (!vi.id) {
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
74
|
+
var url = 'https://www.teachertube.com/';
|
|
75
|
+
|
|
76
|
+
if (vi.list) {
|
|
77
|
+
params['playlist-id'] = vi.list;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (vi.mediaType === this.mediaTypes.CHANNEL) {
|
|
81
|
+
url += 'user/channel/';
|
|
82
|
+
} else {
|
|
83
|
+
url += vi.mediaType + '/';
|
|
84
|
+
}
|
|
85
|
+
url += vi.id;
|
|
86
|
+
|
|
87
|
+
url += combineParams(params);
|
|
88
|
+
|
|
89
|
+
return url;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
TeacherTube.prototype.createEmbedUrl = function(vi, params) {
|
|
93
|
+
if (!vi.id) {
|
|
94
|
+
return undefined;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
var url = 'https://www.teachertube.com/embed/';
|
|
98
|
+
|
|
99
|
+
if (vi.mediaType === this.mediaTypes.VIDEO || vi.mediaType === this.mediaTypes.AUDIO) {
|
|
100
|
+
url += vi.mediaType + '/' + vi.id;
|
|
101
|
+
} else {
|
|
102
|
+
return undefined;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
url += combineParams(params);
|
|
106
|
+
|
|
107
|
+
return url;
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
require('../base').bind(new TeacherTube());
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { VideoInfo } from '../urlParser';
|
|
2
|
+
|
|
3
|
+
export interface TedUrlParameters {
|
|
4
|
+
[key: string]: any;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export type TedMediaTypes = 'video' | 'playlist';
|
|
8
|
+
|
|
9
|
+
export interface TedVideoInfo extends VideoInfo<TedUrlParameters, TedMediaTypes> {
|
|
10
|
+
provider: 'ted';
|
|
11
|
+
list?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export type TedParseResult = TedVideoInfo | undefined;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
const { combineParams } = require('../util');
|
|
2
|
+
|
|
3
|
+
function Ted() {
|
|
4
|
+
this.provider = 'ted';
|
|
5
|
+
this.formats = {
|
|
6
|
+
long: this.createLongUrl,
|
|
7
|
+
embed: this.createEmbedUrl,
|
|
8
|
+
};
|
|
9
|
+
this.mediaTypes = {
|
|
10
|
+
VIDEO: 'video',
|
|
11
|
+
PLAYLIST: 'playlist',
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
module.exports = Ted;
|
|
16
|
+
|
|
17
|
+
Ted.prototype.parseUrl = function(url, result) {
|
|
18
|
+
var match = url.match(/\/(talks|playlists\/(\d+))\/([\w-]+)/i);
|
|
19
|
+
var channel = match ? match[1] : undefined;
|
|
20
|
+
|
|
21
|
+
if (!channel) {
|
|
22
|
+
return result;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
result.channel = channel.split('/')[0];
|
|
26
|
+
result.id = match[3];
|
|
27
|
+
|
|
28
|
+
if (result.channel === 'playlists') {
|
|
29
|
+
result.list = match[2];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
Ted.prototype.parseMediaType = function(result) {
|
|
36
|
+
if (result.id && result.channel === 'playlists') {
|
|
37
|
+
delete result.channel;
|
|
38
|
+
result.mediaType = this.mediaTypes.PLAYLIST;
|
|
39
|
+
}
|
|
40
|
+
if (result.id && result.channel === 'talks') {
|
|
41
|
+
delete result.channel;
|
|
42
|
+
result.mediaType = this.mediaTypes.VIDEO;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return result;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
Ted.prototype.parse = function(url, params) {
|
|
49
|
+
var result = {
|
|
50
|
+
params: params,
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
result = this.parseUrl(url, result);
|
|
54
|
+
result = this.parseMediaType(result);
|
|
55
|
+
|
|
56
|
+
if (!result.id) {
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return result;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
Ted.prototype.createLongUrl = function(vi, params) {
|
|
64
|
+
var url = '';
|
|
65
|
+
|
|
66
|
+
if (vi.mediaType === this.mediaTypes.VIDEO && vi.id) {
|
|
67
|
+
url += 'https://ted.com/talks/' + vi.id;
|
|
68
|
+
}
|
|
69
|
+
else if (vi.mediaType === this.mediaTypes.PLAYLIST && vi.id) {
|
|
70
|
+
url += 'https://ted.com/playlists/' + vi.list + '/' + vi.id;
|
|
71
|
+
} else {
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
url += combineParams(params);
|
|
76
|
+
|
|
77
|
+
return url;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
Ted.prototype.createEmbedUrl = function(vi, params) {
|
|
81
|
+
var url = 'https://embed.ted.com/';
|
|
82
|
+
|
|
83
|
+
if (vi.mediaType === this.mediaTypes.PLAYLIST && vi.id) {
|
|
84
|
+
url += 'playlists/' + vi.list + '/' + vi.id;
|
|
85
|
+
}
|
|
86
|
+
else if (vi.mediaType === this.mediaTypes.VIDEO && vi.id) {
|
|
87
|
+
url += 'talks/' + vi.id;
|
|
88
|
+
} else {
|
|
89
|
+
return undefined;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
url += combineParams(params);
|
|
93
|
+
return url;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
require('../base').bind(new Ted());
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { VideoInfo } from '../urlParser';
|
|
2
|
+
|
|
3
|
+
export interface TiktokUrlParameters {
|
|
4
|
+
[key: string]: any;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export type TiktokMediaTypes = 'video';
|
|
8
|
+
|
|
9
|
+
export interface TiktokVideoInfo extends VideoInfo<TiktokUrlParameters, TiktokMediaTypes> {
|
|
10
|
+
provider: 'tiktok';
|
|
11
|
+
channel: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export type TiktokParseResult = TiktokVideoInfo | undefined;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
const {
|
|
2
|
+
combineParams,
|
|
3
|
+
} = require('../util');
|
|
4
|
+
|
|
5
|
+
function TikTok() {
|
|
6
|
+
this.provider = 'tiktok';
|
|
7
|
+
this.defaultFormat = 'long';
|
|
8
|
+
this.formats = {
|
|
9
|
+
long: this.createLongUrl,
|
|
10
|
+
};
|
|
11
|
+
this.mediaTypes = {
|
|
12
|
+
VIDEO: 'video',
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
module.exports = TikTok;
|
|
17
|
+
|
|
18
|
+
TikTok.prototype.parse = function(url, params) {
|
|
19
|
+
var result = {
|
|
20
|
+
params: params,
|
|
21
|
+
mediaType: this.mediaTypes.VIDEO,
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
var match = url.match(/@([^/]+)\/video\/(\d{19})/);
|
|
25
|
+
|
|
26
|
+
if (!match) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
result.channel = match[1];
|
|
31
|
+
result.id = match[2];
|
|
32
|
+
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
TikTok.prototype.createLongUrl = function(vi, params) {
|
|
37
|
+
var url = '';
|
|
38
|
+
|
|
39
|
+
if (vi.mediaType === this.mediaTypes.VIDEO && vi.id && vi.channel) {
|
|
40
|
+
url += `https://www.tiktok.com/@${vi.channel}/video/${vi.id}`;
|
|
41
|
+
} else {
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
url += combineParams(params);
|
|
46
|
+
|
|
47
|
+
return url;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
require('../base').bind(new TikTok());
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { VideoInfo } from '../urlParser';
|
|
2
|
+
|
|
3
|
+
export interface TwitchUrlParameters {
|
|
4
|
+
[key: string]: any;
|
|
5
|
+
start?: number;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export type TwitchMediaTypes = 'stream' | 'video' | 'clip';
|
|
9
|
+
|
|
10
|
+
export interface TwitchVideoInfo extends VideoInfo<TwitchUrlParameters, TwitchMediaTypes> {
|
|
11
|
+
provider: 'twitch';
|
|
12
|
+
channel?: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export type TwitchParseResult = TwitchVideoInfo | undefined;
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
const {
|
|
2
|
+
combineParams,
|
|
3
|
+
getTime,
|
|
4
|
+
} = require('../util');
|
|
5
|
+
|
|
6
|
+
function Twitch() {
|
|
7
|
+
this.provider = 'twitch';
|
|
8
|
+
this.defaultFormat = 'long';
|
|
9
|
+
this.formats = {
|
|
10
|
+
long: this.createLongUrl,
|
|
11
|
+
embed: this.createEmbedUrl,
|
|
12
|
+
};
|
|
13
|
+
this.mediaTypes = {
|
|
14
|
+
VIDEO: 'video',
|
|
15
|
+
STREAM: 'stream',
|
|
16
|
+
CLIP: 'clip',
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
module.exports = Twitch;
|
|
21
|
+
|
|
22
|
+
Twitch.prototype.seperateId = function(id) {
|
|
23
|
+
return {
|
|
24
|
+
pre: id[0],
|
|
25
|
+
id: id.substr(1),
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
Twitch.prototype.parseChannel = function(result, params) {
|
|
30
|
+
var channel = params.channel || params.utm_content || result.channel;
|
|
31
|
+
delete params.utm_content;
|
|
32
|
+
delete params.channel;
|
|
33
|
+
return channel;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
Twitch.prototype.parseUrl = function(url, result, params) {
|
|
37
|
+
var match;
|
|
38
|
+
match = url.match(
|
|
39
|
+
/(clips\.)?twitch\.tv\/(?:(?:videos\/(\d+))|(\w+(?:-[\w\d-]+)?)(?:\/clip\/(\w+))?)/i
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
if (match && match[2]) { //video
|
|
43
|
+
result.id = 'v' + match[2];
|
|
44
|
+
} else if (params.video) { //video embed
|
|
45
|
+
result.id = params.video;
|
|
46
|
+
delete params.video;
|
|
47
|
+
} else if (params.clip) { //clips embed
|
|
48
|
+
result.id = params.clip;
|
|
49
|
+
result.isClip = true;
|
|
50
|
+
delete params.clip;
|
|
51
|
+
} else if (match && match[1] && match[3]) { //clips.twitch.tv/id
|
|
52
|
+
result.id = match[3];
|
|
53
|
+
result.isClip = true;
|
|
54
|
+
} else if (match && match[3] && match[4]) { //twitch.tv/channel/clip/id
|
|
55
|
+
result.channel = match[3];
|
|
56
|
+
result.id = match[4];
|
|
57
|
+
result.isClip = true;
|
|
58
|
+
} else if (match && match[3]) {
|
|
59
|
+
result.channel = match[3];
|
|
60
|
+
}
|
|
61
|
+
return result;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
Twitch.prototype.parseMediaType = function(result) {
|
|
65
|
+
var mediaType;
|
|
66
|
+
if (result.id) {
|
|
67
|
+
if (result.isClip) {
|
|
68
|
+
mediaType = this.mediaTypes.CLIP;
|
|
69
|
+
delete result.isClip;
|
|
70
|
+
} else {
|
|
71
|
+
mediaType = this.mediaTypes.VIDEO;
|
|
72
|
+
}
|
|
73
|
+
} else if (result.channel) {
|
|
74
|
+
mediaType = this.mediaTypes.STREAM;
|
|
75
|
+
}
|
|
76
|
+
return mediaType;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
Twitch.prototype.parseParameters = function(params) {
|
|
80
|
+
if (params.t) {
|
|
81
|
+
params.start = getTime(params.t);
|
|
82
|
+
delete params.t;
|
|
83
|
+
}
|
|
84
|
+
return params;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
Twitch.prototype.parse = function(url, params) {
|
|
88
|
+
var _this = this;
|
|
89
|
+
var result = {};
|
|
90
|
+
result = _this.parseUrl(url, result, params);
|
|
91
|
+
result.channel = _this.parseChannel(result, params);
|
|
92
|
+
result.mediaType = _this.parseMediaType(result);
|
|
93
|
+
result.params = _this.parseParameters(params);
|
|
94
|
+
return result.channel || result.id ? result : undefined;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
Twitch.prototype.createLongUrl = function(vi, params) {
|
|
98
|
+
var url = '';
|
|
99
|
+
|
|
100
|
+
if (vi.mediaType === this.mediaTypes.STREAM && vi.channel) {
|
|
101
|
+
url = 'https://twitch.tv/' + vi.channel;
|
|
102
|
+
}
|
|
103
|
+
else if (vi.mediaType === this.mediaTypes.VIDEO && vi.id) {
|
|
104
|
+
var sep = this.seperateId(vi.id);
|
|
105
|
+
url = 'https://twitch.tv/videos/' + sep.id;
|
|
106
|
+
if (params.start) {
|
|
107
|
+
params.t = params.start + 's';
|
|
108
|
+
delete params.start;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
else if (vi.mediaType === this.mediaTypes.CLIP && vi.id) {
|
|
112
|
+
if (vi.channel) {
|
|
113
|
+
url = 'https://www.twitch.tv/' + vi.channel + '/clip/' + vi.id;
|
|
114
|
+
} else {
|
|
115
|
+
url = 'https://clips.twitch.tv/' + vi.id;
|
|
116
|
+
}
|
|
117
|
+
} else {
|
|
118
|
+
return undefined;
|
|
119
|
+
}
|
|
120
|
+
url += combineParams(params);
|
|
121
|
+
|
|
122
|
+
return url;
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
Twitch.prototype.createEmbedUrl = function(vi, params) {
|
|
126
|
+
var url = 'https://player.twitch.tv/';
|
|
127
|
+
|
|
128
|
+
if (vi.mediaType === this.mediaTypes.STREAM && vi.channel) {
|
|
129
|
+
params.channel = vi.channel;
|
|
130
|
+
}
|
|
131
|
+
else if (vi.mediaType === this.mediaTypes.VIDEO && vi.id) {
|
|
132
|
+
params.video = vi.id;
|
|
133
|
+
if (params.start) {
|
|
134
|
+
params.t = params.start + 's';
|
|
135
|
+
delete params.start;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
else if (vi.mediaType === this.mediaTypes.CLIP && vi.id) {
|
|
139
|
+
url = 'https://clips.twitch.tv/embed';
|
|
140
|
+
params.clip = vi.id;
|
|
141
|
+
} else {
|
|
142
|
+
return undefined;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
url += combineParams(params);
|
|
146
|
+
|
|
147
|
+
return url;
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
require('../base').bind(new Twitch());
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { VideoInfo } from '../urlParser';
|
|
2
|
+
|
|
3
|
+
export interface VimeoUrlParameters {
|
|
4
|
+
[key: string]: any;
|
|
5
|
+
start?: number;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export type VimeoMediaTypes = 'video';
|
|
9
|
+
|
|
10
|
+
export interface VimeoVideoInfo extends VideoInfo<VimeoUrlParameters, VimeoMediaTypes> {
|
|
11
|
+
provider: 'vimeo';
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export type VimeoParseResult = VimeoVideoInfo | undefined;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
const { combineParams, getTime } = require('../util');
|
|
2
|
+
|
|
3
|
+
function Vimeo() {
|
|
4
|
+
this.provider = 'vimeo';
|
|
5
|
+
this.alternatives = ['vimeopro'];
|
|
6
|
+
this.defaultFormat = 'long';
|
|
7
|
+
this.formats = {
|
|
8
|
+
long: this.createLongUrl,
|
|
9
|
+
embed: this.createEmbedUrl,
|
|
10
|
+
};
|
|
11
|
+
this.mediaTypes = {
|
|
12
|
+
VIDEO: 'video',
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
module.exports = Vimeo;
|
|
17
|
+
|
|
18
|
+
Vimeo.prototype.parseUrl = function(url) {
|
|
19
|
+
var match = url.match(
|
|
20
|
+
/(?:\/showcase\/\d+)?(?:\/(?:channels\/[\w]+|(?:(?:album\/\d+|groups\/[\w]+)\/)?videos?))?\/(\d+)/i
|
|
21
|
+
);
|
|
22
|
+
return match ? match[1] : undefined;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
Vimeo.prototype.parseHash = function(url) {
|
|
26
|
+
var match = url.match(/\/\d+\/(\w+)$/i);
|
|
27
|
+
return match ? match[1] : undefined;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
Vimeo.prototype.parseParameters = function(params) {
|
|
31
|
+
if (params.t) {
|
|
32
|
+
params.start = getTime(params.t);
|
|
33
|
+
delete params.t;
|
|
34
|
+
}
|
|
35
|
+
if (params.h) {
|
|
36
|
+
params.hash = params.h;
|
|
37
|
+
delete params.h;
|
|
38
|
+
}
|
|
39
|
+
return params;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
Vimeo.prototype.parse = function(url, params) {
|
|
43
|
+
var result = {
|
|
44
|
+
mediaType: this.mediaTypes.VIDEO,
|
|
45
|
+
params: this.parseParameters(params),
|
|
46
|
+
id: this.parseUrl(url),
|
|
47
|
+
};
|
|
48
|
+
var hash = this.parseHash(url, params);
|
|
49
|
+
if (hash) {
|
|
50
|
+
result.params.hash = hash;
|
|
51
|
+
}
|
|
52
|
+
return result.id ? result : undefined;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
Vimeo.prototype.createUrl = function(baseUrl, vi, params, type) {
|
|
56
|
+
if (!vi.id || vi.mediaType !== this.mediaTypes.VIDEO) {
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
var url = baseUrl + vi.id;
|
|
61
|
+
var startTime = params.start;
|
|
62
|
+
delete params.start;
|
|
63
|
+
|
|
64
|
+
if (params.hash) {
|
|
65
|
+
if (type === 'embed') {
|
|
66
|
+
params.h = params.hash;
|
|
67
|
+
} else if (type === 'long') {
|
|
68
|
+
url += '/' + params.hash;
|
|
69
|
+
}
|
|
70
|
+
delete params.hash;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
url += combineParams(params);
|
|
74
|
+
|
|
75
|
+
if (startTime) {
|
|
76
|
+
url += '#t=' + startTime;
|
|
77
|
+
}
|
|
78
|
+
return url;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
Vimeo.prototype.createLongUrl = function(vi, params) {
|
|
82
|
+
return this.createUrl('https://vimeo.com/', vi, params, 'long');
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
Vimeo.prototype.createEmbedUrl = function(vi, params) {
|
|
86
|
+
return this.createUrl('//player.vimeo.com/video/', vi, params, 'embed');
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
require('../base').bind(new Vimeo());
|