aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/models/video/video.ts
diff options
context:
space:
mode:
Diffstat (limited to 'server/models/video/video.ts')
-rw-r--r--server/models/video/video.ts111
1 files changed, 60 insertions, 51 deletions
diff --git a/server/models/video/video.ts b/server/models/video/video.ts
index b59df397d..7b1f0bc31 100644
--- a/server/models/video/video.ts
+++ b/server/models/video/video.ts
@@ -36,7 +36,7 @@ import {
36 Table, 36 Table,
37 UpdatedAt 37 UpdatedAt
38} from 'sequelize-typescript' 38} from 'sequelize-typescript'
39import { UserRight, VideoPrivacy, VideoResolution, VideoState } from '../../../shared' 39import { UserRight, VideoPrivacy, VideoState } from '../../../shared'
40import { VideoTorrentObject } from '../../../shared/models/activitypub/objects' 40import { VideoTorrentObject } from '../../../shared/models/activitypub/objects'
41import { Video, VideoDetails, VideoFile } from '../../../shared/models/videos' 41import { Video, VideoDetails, VideoFile } from '../../../shared/models/videos'
42import { VideoFilter } from '../../../shared/models/videos/video-query.type' 42import { VideoFilter } from '../../../shared/models/videos/video-query.type'
@@ -111,7 +111,6 @@ import {
111 videoModelToFormattedJSON 111 videoModelToFormattedJSON
112} from './video-format-utils' 112} from './video-format-utils'
113import { UserVideoHistoryModel } from '../account/user-video-history' 113import { UserVideoHistoryModel } from '../account/user-video-history'
114import { UserModel } from '../account/user'
115import { VideoImportModel } from './video-import' 114import { VideoImportModel } from './video-import'
116import { VideoStreamingPlaylistModel } from './video-streaming-playlist' 115import { VideoStreamingPlaylistModel } from './video-streaming-playlist'
117import { VideoPlaylistElementModel } from './video-playlist-element' 116import { VideoPlaylistElementModel } from './video-playlist-element'
@@ -120,6 +119,24 @@ import { ThumbnailModel } from './thumbnail'
120import { ThumbnailType } from '../../../shared/models/videos/thumbnail.type' 119import { ThumbnailType } from '../../../shared/models/videos/thumbnail.type'
121import { createTorrentPromise } from '../../helpers/webtorrent' 120import { createTorrentPromise } from '../../helpers/webtorrent'
122import { VideoStreamingPlaylistType } from '../../../shared/models/videos/video-streaming-playlist.type' 121import { VideoStreamingPlaylistType } from '../../../shared/models/videos/video-streaming-playlist.type'
122import {
123 MChannel,
124 MChannelActorAccountDefault,
125 MChannelId,
126 MUserAccountId,
127 MUserId,
128 MVideoAccountAllFiles,
129 MVideoAccountLight,
130 MVideoDetails,
131 MVideoFullLight,
132 MVideoIdThumbnail,
133 MVideoThumbnail,
134 MVideoWithAllFiles,
135 MVideoWithBlacklistThumbnailScheduled,
136 MVideoWithRights
137} from '../../typings/models'
138import { MVideoFile, MVideoFileRedundanciesOpt } from '../../typings/models/video/video-file'
139import { MThumbnail } from '../../typings/models/video/thumbnail'
123 140
124// FIXME: Define indexes here because there is an issue with TS and Sequelize.literal when called directly in the annotation 141// FIXME: Define indexes here because there is an issue with TS and Sequelize.literal when called directly in the annotation
125const indexes: (ModelIndexesOptions & { where?: WhereOptions })[] = [ 142const indexes: (ModelIndexesOptions & { where?: WhereOptions })[] = [
@@ -232,8 +249,8 @@ export type AvailableForListIDsOptions = {
232 videoPlaylistId?: number 249 videoPlaylistId?: number
233 250
234 trendingDays?: number 251 trendingDays?: number
235 user?: UserModel, 252 user?: MUserAccountId
236 historyOfUser?: UserModel 253 historyOfUser?: MUserId
237 254
238 baseWhere?: WhereOptions[] 255 baseWhere?: WhereOptions[]
239} 256}
@@ -634,7 +651,7 @@ export type AvailableForListIDsOptions = {
634 [ ScopeNames.WITH_BLACKLISTED ]: { 651 [ ScopeNames.WITH_BLACKLISTED ]: {
635 include: [ 652 include: [
636 { 653 {
637 attributes: [ 'id', 'reason' ], 654 attributes: [ 'id', 'reason', 'unfederated' ],
638 model: VideoBlacklistModel, 655 model: VideoBlacklistModel,
639 required: false 656 required: false
640 } 657 }
@@ -989,18 +1006,16 @@ export class VideoModel extends Model<VideoModel> {
989 VideoCaptions: VideoCaptionModel[] 1006 VideoCaptions: VideoCaptionModel[]
990 1007
991 @BeforeDestroy 1008 @BeforeDestroy
992 static async sendDelete (instance: VideoModel, options) { 1009 static async sendDelete (instance: MVideoAccountLight, options) {
993 if (instance.isOwned()) { 1010 if (instance.isOwned()) {
994 if (!instance.VideoChannel) { 1011 if (!instance.VideoChannel) {
995 instance.VideoChannel = await instance.$get('VideoChannel', { 1012 instance.VideoChannel = await instance.$get('VideoChannel', {
996 include: [ 1013 include: [
997 { 1014 ActorModel,
998 model: AccountModel, 1015 AccountModel
999 include: [ ActorModel ]
1000 }
1001 ], 1016 ],
1002 transaction: options.transaction 1017 transaction: options.transaction
1003 }) as VideoChannelModel 1018 }) as MChannelActorAccountDefault
1004 } 1019 }
1005 1020
1006 return sendDeleteVideo(instance, options.transaction) 1021 return sendDeleteVideo(instance, options.transaction)
@@ -1039,7 +1054,7 @@ export class VideoModel extends Model<VideoModel> {
1039 return undefined 1054 return undefined
1040 } 1055 }
1041 1056
1042 static listLocal () { 1057 static listLocal (): Bluebird<MVideoWithAllFiles[]> {
1043 const query = { 1058 const query = {
1044 where: { 1059 where: {
1045 remote: false 1060 remote: false
@@ -1159,7 +1174,7 @@ export class VideoModel extends Model<VideoModel> {
1159 }) 1174 })
1160 } 1175 }
1161 1176
1162 static listUserVideosForApi (accountId: number, start: number, count: number, sort: string, withFiles = false) { 1177 static listUserVideosForApi (accountId: number, start: number, count: number, sort: string) {
1163 function buildBaseQuery (): FindOptions { 1178 function buildBaseQuery (): FindOptions {
1164 return { 1179 return {
1165 offset: start, 1180 offset: start,
@@ -1192,19 +1207,12 @@ export class VideoModel extends Model<VideoModel> {
1192 ScopeNames.WITH_THUMBNAILS 1207 ScopeNames.WITH_THUMBNAILS
1193 ] 1208 ]
1194 1209
1195 if (withFiles === true) {
1196 findQuery.include.push({
1197 model: VideoFileModel.unscoped(),
1198 required: true
1199 })
1200 }
1201
1202 return Promise.all([ 1210 return Promise.all([
1203 VideoModel.count(countQuery), 1211 VideoModel.count(countQuery),
1204 VideoModel.scope(findScopes).findAll(findQuery) 1212 VideoModel.scope(findScopes).findAll(findQuery)
1205 ]).then(([ count, rows ]) => { 1213 ]).then(([ count, rows ]) => {
1206 return { 1214 return {
1207 data: rows, 1215 data: rows as MVideoWithBlacklistThumbnailScheduled[],
1208 total: count 1216 total: count
1209 } 1217 }
1210 }) 1218 })
@@ -1228,8 +1236,8 @@ export class VideoModel extends Model<VideoModel> {
1228 followerActorId?: number 1236 followerActorId?: number
1229 videoPlaylistId?: number, 1237 videoPlaylistId?: number,
1230 trendingDays?: number, 1238 trendingDays?: number,
1231 user?: UserModel, 1239 user?: MUserAccountId,
1232 historyOfUser?: UserModel 1240 historyOfUser?: MUserId
1233 }, countVideos = true) { 1241 }, countVideos = true) {
1234 if (options.filter && options.filter === 'all-local' && !options.user.hasRight(UserRight.SEE_ALL_VIDEOS)) { 1242 if (options.filter && options.filter === 'all-local' && !options.user.hasRight(UserRight.SEE_ALL_VIDEOS)) {
1235 throw new Error('Try to filter all-local but no user has not the see all videos right') 1243 throw new Error('Try to filter all-local but no user has not the see all videos right')
@@ -1294,7 +1302,7 @@ export class VideoModel extends Model<VideoModel> {
1294 tagsAllOf?: string[] 1302 tagsAllOf?: string[]
1295 durationMin?: number // seconds 1303 durationMin?: number // seconds
1296 durationMax?: number // seconds 1304 durationMax?: number // seconds
1297 user?: UserModel, 1305 user?: MUserAccountId,
1298 filter?: VideoFilter 1306 filter?: VideoFilter
1299 }) { 1307 }) {
1300 const whereAnd = [] 1308 const whereAnd = []
@@ -1387,7 +1395,7 @@ export class VideoModel extends Model<VideoModel> {
1387 return VideoModel.getAvailableForApi(query, queryOptions) 1395 return VideoModel.getAvailableForApi(query, queryOptions)
1388 } 1396 }
1389 1397
1390 static load (id: number | string, t?: Transaction) { 1398 static load (id: number | string, t?: Transaction): Bluebird<MVideoThumbnail> {
1391 const where = buildWhereIdOrUUID(id) 1399 const where = buildWhereIdOrUUID(id)
1392 const options = { 1400 const options = {
1393 where, 1401 where,
@@ -1397,7 +1405,7 @@ export class VideoModel extends Model<VideoModel> {
1397 return VideoModel.scope(ScopeNames.WITH_THUMBNAILS).findOne(options) 1405 return VideoModel.scope(ScopeNames.WITH_THUMBNAILS).findOne(options)
1398 } 1406 }
1399 1407
1400 static loadWithRights (id: number | string, t?: Transaction) { 1408 static loadWithRights (id: number | string, t?: Transaction): Bluebird<MVideoWithRights> {
1401 const where = buildWhereIdOrUUID(id) 1409 const where = buildWhereIdOrUUID(id)
1402 const options = { 1410 const options = {
1403 where, 1411 where,
@@ -1411,7 +1419,7 @@ export class VideoModel extends Model<VideoModel> {
1411 ]).findOne(options) 1419 ]).findOne(options)
1412 } 1420 }
1413 1421
1414 static loadOnlyId (id: number | string, t?: Transaction) { 1422 static loadOnlyId (id: number | string, t?: Transaction): Bluebird<MVideoIdThumbnail> {
1415 const where = buildWhereIdOrUUID(id) 1423 const where = buildWhereIdOrUUID(id)
1416 1424
1417 const options = { 1425 const options = {
@@ -1423,7 +1431,7 @@ export class VideoModel extends Model<VideoModel> {
1423 return VideoModel.scope(ScopeNames.WITH_THUMBNAILS).findOne(options) 1431 return VideoModel.scope(ScopeNames.WITH_THUMBNAILS).findOne(options)
1424 } 1432 }
1425 1433
1426 static loadWithFiles (id: number | string, t?: Transaction, logging?: boolean) { 1434 static loadWithFiles (id: number | string, t?: Transaction, logging?: boolean): Bluebird<MVideoWithAllFiles> {
1427 const where = buildWhereIdOrUUID(id) 1435 const where = buildWhereIdOrUUID(id)
1428 1436
1429 const query = { 1437 const query = {
@@ -1439,7 +1447,7 @@ export class VideoModel extends Model<VideoModel> {
1439 ]).findOne(query) 1447 ]).findOne(query)
1440 } 1448 }
1441 1449
1442 static loadByUUID (uuid: string) { 1450 static loadByUUID (uuid: string): Bluebird<MVideoThumbnail> {
1443 const options = { 1451 const options = {
1444 where: { 1452 where: {
1445 uuid 1453 uuid
@@ -1449,7 +1457,7 @@ export class VideoModel extends Model<VideoModel> {
1449 return VideoModel.scope(ScopeNames.WITH_THUMBNAILS).findOne(options) 1457 return VideoModel.scope(ScopeNames.WITH_THUMBNAILS).findOne(options)
1450 } 1458 }
1451 1459
1452 static loadByUrl (url: string, transaction?: Transaction) { 1460 static loadByUrl (url: string, transaction?: Transaction): Bluebird<MVideoThumbnail> {
1453 const query: FindOptions = { 1461 const query: FindOptions = {
1454 where: { 1462 where: {
1455 url 1463 url
@@ -1460,7 +1468,7 @@ export class VideoModel extends Model<VideoModel> {
1460 return VideoModel.scope(ScopeNames.WITH_THUMBNAILS).findOne(query) 1468 return VideoModel.scope(ScopeNames.WITH_THUMBNAILS).findOne(query)
1461 } 1469 }
1462 1470
1463 static loadByUrlAndPopulateAccount (url: string, transaction?: Transaction) { 1471 static loadByUrlAndPopulateAccount (url: string, transaction?: Transaction): Bluebird<MVideoAccountAllFiles> {
1464 const query: FindOptions = { 1472 const query: FindOptions = {
1465 where: { 1473 where: {
1466 url 1474 url
@@ -1472,11 +1480,12 @@ export class VideoModel extends Model<VideoModel> {
1472 ScopeNames.WITH_ACCOUNT_DETAILS, 1480 ScopeNames.WITH_ACCOUNT_DETAILS,
1473 ScopeNames.WITH_FILES, 1481 ScopeNames.WITH_FILES,
1474 ScopeNames.WITH_STREAMING_PLAYLISTS, 1482 ScopeNames.WITH_STREAMING_PLAYLISTS,
1475 ScopeNames.WITH_THUMBNAILS 1483 ScopeNames.WITH_THUMBNAILS,
1484 ScopeNames.WITH_BLACKLISTED
1476 ]).findOne(query) 1485 ]).findOne(query)
1477 } 1486 }
1478 1487
1479 static loadAndPopulateAccountAndServerAndTags (id: number | string, t?: Transaction, userId?: number) { 1488 static loadAndPopulateAccountAndServerAndTags (id: number | string, t?: Transaction, userId?: number): Bluebird<MVideoFullLight> {
1480 const where = buildWhereIdOrUUID(id) 1489 const where = buildWhereIdOrUUID(id)
1481 1490
1482 const options = { 1491 const options = {
@@ -1508,7 +1517,7 @@ export class VideoModel extends Model<VideoModel> {
1508 id: number | string, 1517 id: number | string,
1509 t?: Transaction, 1518 t?: Transaction,
1510 userId?: number 1519 userId?: number
1511 }) { 1520 }): Bluebird<MVideoDetails> {
1512 const { id, t, userId } = parameters 1521 const { id, t, userId } = parameters
1513 const where = buildWhereIdOrUUID(id) 1522 const where = buildWhereIdOrUUID(id)
1514 1523
@@ -1586,7 +1595,7 @@ export class VideoModel extends Model<VideoModel> {
1586 .then(results => results.length === 1) 1595 .then(results => results.length === 1)
1587 } 1596 }
1588 1597
1589 static bulkUpdateSupportField (videoChannel: VideoChannelModel, t: Transaction) { 1598 static bulkUpdateSupportField (videoChannel: MChannel, t: Transaction) {
1590 const options = { 1599 const options = {
1591 where: { 1600 where: {
1592 channelId: videoChannel.id 1601 channelId: videoChannel.id
@@ -1597,7 +1606,7 @@ export class VideoModel extends Model<VideoModel> {
1597 return VideoModel.update({ support: videoChannel.support }, options) 1606 return VideoModel.update({ support: videoChannel.support }, options)
1598 } 1607 }
1599 1608
1600 static getAllIdsFromChannel (videoChannel: VideoChannelModel) { 1609 static getAllIdsFromChannel (videoChannel: MChannelId): Bluebird<number[]> {
1601 const query = { 1610 const query = {
1602 attributes: [ 'id' ], 1611 attributes: [ 'id' ],
1603 where: { 1612 where: {
@@ -1769,7 +1778,7 @@ export class VideoModel extends Model<VideoModel> {
1769 return this.VideoFiles.find(f => f.resolution === resolution) 1778 return this.VideoFiles.find(f => f.resolution === resolution)
1770 } 1779 }
1771 1780
1772 async addAndSaveThumbnail (thumbnail: ThumbnailModel, transaction: Transaction) { 1781 async addAndSaveThumbnail (thumbnail: MThumbnail, transaction: Transaction) {
1773 thumbnail.videoId = this.id 1782 thumbnail.videoId = this.id
1774 1783
1775 const savedThumbnail = await thumbnail.save({ transaction }) 1784 const savedThumbnail = await thumbnail.save({ transaction })
@@ -1782,7 +1791,7 @@ export class VideoModel extends Model<VideoModel> {
1782 this.Thumbnails.push(savedThumbnail) 1791 this.Thumbnails.push(savedThumbnail)
1783 } 1792 }
1784 1793
1785 getVideoFilename (videoFile: VideoFileModel) { 1794 getVideoFilename (videoFile: MVideoFile) {
1786 return this.uuid + '-' + videoFile.resolution + videoFile.extname 1795 return this.uuid + '-' + videoFile.resolution + videoFile.extname
1787 } 1796 }
1788 1797
@@ -1806,7 +1815,7 @@ export class VideoModel extends Model<VideoModel> {
1806 return this.Thumbnails.find(t => t.type === ThumbnailType.PREVIEW) 1815 return this.Thumbnails.find(t => t.type === ThumbnailType.PREVIEW)
1807 } 1816 }
1808 1817
1809 getTorrentFileName (videoFile: VideoFileModel) { 1818 getTorrentFileName (videoFile: MVideoFile) {
1810 const extension = '.torrent' 1819 const extension = '.torrent'
1811 return this.uuid + '-' + videoFile.resolution + extension 1820 return this.uuid + '-' + videoFile.resolution + extension
1812 } 1821 }
@@ -1815,15 +1824,15 @@ export class VideoModel extends Model<VideoModel> {
1815 return this.remote === false 1824 return this.remote === false
1816 } 1825 }
1817 1826
1818 getTorrentFilePath (videoFile: VideoFileModel) { 1827 getTorrentFilePath (videoFile: MVideoFile) {
1819 return join(CONFIG.STORAGE.TORRENTS_DIR, this.getTorrentFileName(videoFile)) 1828 return join(CONFIG.STORAGE.TORRENTS_DIR, this.getTorrentFileName(videoFile))
1820 } 1829 }
1821 1830
1822 getVideoFilePath (videoFile: VideoFileModel) { 1831 getVideoFilePath (videoFile: MVideoFile) {
1823 return join(CONFIG.STORAGE.VIDEOS_DIR, this.getVideoFilename(videoFile)) 1832 return join(CONFIG.STORAGE.VIDEOS_DIR, this.getVideoFilename(videoFile))
1824 } 1833 }
1825 1834
1826 async createTorrentAndSetInfoHash (videoFile: VideoFileModel) { 1835 async createTorrentAndSetInfoHash (videoFile: MVideoFile) {
1827 const options = { 1836 const options = {
1828 // Keep the extname, it's used by the client to stream the file inside a web browser 1837 // Keep the extname, it's used by the client to stream the file inside a web browser
1829 name: `${this.name} ${videoFile.resolution}p${videoFile.extname}`, 1838 name: `${this.name} ${videoFile.resolution}p${videoFile.extname}`,
@@ -1908,7 +1917,7 @@ export class VideoModel extends Model<VideoModel> {
1908 return this.VideoStreamingPlaylists.find(p => p.type === VideoStreamingPlaylistType.HLS) 1917 return this.VideoStreamingPlaylists.find(p => p.type === VideoStreamingPlaylistType.HLS)
1909 } 1918 }
1910 1919
1911 removeFile (videoFile: VideoFileModel, isRedundancy = false) { 1920 removeFile (videoFile: MVideoFile, isRedundancy = false) {
1912 const baseDir = isRedundancy ? CONFIG.STORAGE.REDUNDANCY_DIR : CONFIG.STORAGE.VIDEOS_DIR 1921 const baseDir = isRedundancy ? CONFIG.STORAGE.REDUNDANCY_DIR : CONFIG.STORAGE.VIDEOS_DIR
1913 1922
1914 const filePath = join(baseDir, this.getVideoFilename(videoFile)) 1923 const filePath = join(baseDir, this.getVideoFilename(videoFile))
@@ -1916,7 +1925,7 @@ export class VideoModel extends Model<VideoModel> {
1916 .catch(err => logger.warn('Cannot delete file %s.', filePath, { err })) 1925 .catch(err => logger.warn('Cannot delete file %s.', filePath, { err }))
1917 } 1926 }
1918 1927
1919 removeTorrent (videoFile: VideoFileModel) { 1928 removeTorrent (videoFile: MVideoFile) {
1920 const torrentPath = join(CONFIG.STORAGE.TORRENTS_DIR, this.getTorrentFileName(videoFile)) 1929 const torrentPath = join(CONFIG.STORAGE.TORRENTS_DIR, this.getTorrentFileName(videoFile))
1921 return remove(torrentPath) 1930 return remove(torrentPath)
1922 .catch(err => logger.warn('Cannot delete torrent %s.', torrentPath, { err })) 1931 .catch(err => logger.warn('Cannot delete torrent %s.', torrentPath, { err }))
@@ -1957,7 +1966,7 @@ export class VideoModel extends Model<VideoModel> {
1957 return { baseUrlHttp, baseUrlWs } 1966 return { baseUrlHttp, baseUrlWs }
1958 } 1967 }
1959 1968
1960 generateMagnetUri (videoFile: VideoFileModel, baseUrlHttp: string, baseUrlWs: string) { 1969 generateMagnetUri (videoFile: MVideoFileRedundanciesOpt, baseUrlHttp: string, baseUrlWs: string) {
1961 const xs = this.getTorrentUrl(videoFile, baseUrlHttp) 1970 const xs = this.getTorrentUrl(videoFile, baseUrlHttp)
1962 const announce = this.getTrackerUrls(baseUrlHttp, baseUrlWs) 1971 const announce = this.getTrackerUrls(baseUrlHttp, baseUrlWs)
1963 let urlList = [ this.getVideoFileUrl(videoFile, baseUrlHttp) ] 1972 let urlList = [ this.getVideoFileUrl(videoFile, baseUrlHttp) ]
@@ -1980,27 +1989,27 @@ export class VideoModel extends Model<VideoModel> {
1980 return [ baseUrlWs + '/tracker/socket', baseUrlHttp + '/tracker/announce' ] 1989 return [ baseUrlWs + '/tracker/socket', baseUrlHttp + '/tracker/announce' ]
1981 } 1990 }
1982 1991
1983 getTorrentUrl (videoFile: VideoFileModel, baseUrlHttp: string) { 1992 getTorrentUrl (videoFile: MVideoFile, baseUrlHttp: string) {
1984 return baseUrlHttp + STATIC_PATHS.TORRENTS + this.getTorrentFileName(videoFile) 1993 return baseUrlHttp + STATIC_PATHS.TORRENTS + this.getTorrentFileName(videoFile)
1985 } 1994 }
1986 1995
1987 getTorrentDownloadUrl (videoFile: VideoFileModel, baseUrlHttp: string) { 1996 getTorrentDownloadUrl (videoFile: MVideoFile, baseUrlHttp: string) {
1988 return baseUrlHttp + STATIC_DOWNLOAD_PATHS.TORRENTS + this.getTorrentFileName(videoFile) 1997 return baseUrlHttp + STATIC_DOWNLOAD_PATHS.TORRENTS + this.getTorrentFileName(videoFile)
1989 } 1998 }
1990 1999
1991 getVideoFileUrl (videoFile: VideoFileModel, baseUrlHttp: string) { 2000 getVideoFileUrl (videoFile: MVideoFile, baseUrlHttp: string) {
1992 return baseUrlHttp + STATIC_PATHS.WEBSEED + this.getVideoFilename(videoFile) 2001 return baseUrlHttp + STATIC_PATHS.WEBSEED + this.getVideoFilename(videoFile)
1993 } 2002 }
1994 2003
1995 getVideoRedundancyUrl (videoFile: VideoFileModel, baseUrlHttp: string) { 2004 getVideoRedundancyUrl (videoFile: MVideoFile, baseUrlHttp: string) {
1996 return baseUrlHttp + STATIC_PATHS.REDUNDANCY + this.getVideoFilename(videoFile) 2005 return baseUrlHttp + STATIC_PATHS.REDUNDANCY + this.getVideoFilename(videoFile)
1997 } 2006 }
1998 2007
1999 getVideoFileDownloadUrl (videoFile: VideoFileModel, baseUrlHttp: string) { 2008 getVideoFileDownloadUrl (videoFile: MVideoFile, baseUrlHttp: string) {
2000 return baseUrlHttp + STATIC_DOWNLOAD_PATHS.VIDEOS + this.getVideoFilename(videoFile) 2009 return baseUrlHttp + STATIC_DOWNLOAD_PATHS.VIDEOS + this.getVideoFilename(videoFile)
2001 } 2010 }
2002 2011
2003 getBandwidthBits (videoFile: VideoFileModel) { 2012 getBandwidthBits (videoFile: MVideoFile) {
2004 return Math.ceil((videoFile.size * 8) / this.duration) 2013 return Math.ceil((videoFile.size * 8) / this.duration)
2005 } 2014 }
2006} 2015}