aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/models/video
diff options
context:
space:
mode:
Diffstat (limited to 'server/models/video')
-rw-r--r--server/models/video/video-caption.ts58
-rw-r--r--server/models/video/video-playlist.ts2
2 files changed, 41 insertions, 19 deletions
diff --git a/server/models/video/video-caption.ts b/server/models/video/video-caption.ts
index e8e883dd0..a1553ea15 100644
--- a/server/models/video/video-caption.ts
+++ b/server/models/video/video-caption.ts
@@ -16,7 +16,7 @@ import {
16 UpdatedAt 16 UpdatedAt
17} from 'sequelize-typescript' 17} from 'sequelize-typescript'
18import { buildRemoteVideoBaseUrl } from '@server/helpers/activitypub' 18import { buildRemoteVideoBaseUrl } from '@server/helpers/activitypub'
19import { MVideoAccountLight, MVideoCaptionFormattable, MVideoCaptionVideo } from '@server/types/models' 19import { MVideoAccountLight, MVideoCaption, MVideoCaptionFormattable, MVideoCaptionVideo } from '@server/types/models'
20import { VideoCaption } from '../../../shared/models/videos/caption/video-caption.model' 20import { VideoCaption } from '../../../shared/models/videos/caption/video-caption.model'
21import { isVideoCaptionLanguageValid } from '../../helpers/custom-validators/video-captions' 21import { isVideoCaptionLanguageValid } from '../../helpers/custom-validators/video-captions'
22import { logger } from '../../helpers/logger' 22import { logger } from '../../helpers/logger'
@@ -24,6 +24,7 @@ import { CONFIG } from '../../initializers/config'
24import { CONSTRAINTS_FIELDS, LAZY_STATIC_PATHS, VIDEO_LANGUAGES, WEBSERVER } from '../../initializers/constants' 24import { CONSTRAINTS_FIELDS, LAZY_STATIC_PATHS, VIDEO_LANGUAGES, WEBSERVER } from '../../initializers/constants'
25import { buildWhereIdOrUUID, throwIfNotValid } from '../utils' 25import { buildWhereIdOrUUID, throwIfNotValid } from '../utils'
26import { VideoModel } from './video' 26import { VideoModel } from './video'
27import { v4 as uuidv4 } from 'uuid'
27 28
28export enum ScopeNames { 29export enum ScopeNames {
29 WITH_VIDEO_UUID_AND_REMOTE = 'WITH_VIDEO_UUID_AND_REMOTE' 30 WITH_VIDEO_UUID_AND_REMOTE = 'WITH_VIDEO_UUID_AND_REMOTE'
@@ -45,6 +46,10 @@ export enum ScopeNames {
45 tableName: 'videoCaption', 46 tableName: 'videoCaption',
46 indexes: [ 47 indexes: [
47 { 48 {
49 fields: [ 'filename' ],
50 unique: true
51 },
52 {
48 fields: [ 'videoId' ] 53 fields: [ 'videoId' ]
49 }, 54 },
50 { 55 {
@@ -65,6 +70,10 @@ export class VideoCaptionModel extends Model {
65 @Column 70 @Column
66 language: string 71 language: string
67 72
73 @AllowNull(false)
74 @Column
75 filename: string
76
68 @AllowNull(true) 77 @AllowNull(true)
69 @Column(DataType.STRING(CONSTRAINTS_FIELDS.COMMONS.URL.max)) 78 @Column(DataType.STRING(CONSTRAINTS_FIELDS.COMMONS.URL.max))
70 fileUrl: string 79 fileUrl: string
@@ -88,12 +97,12 @@ export class VideoCaptionModel extends Model {
88 } 97 }
89 98
90 if (instance.isOwned()) { 99 if (instance.isOwned()) {
91 logger.info('Removing captions %s of video %s.', instance.Video.uuid, instance.language) 100 logger.info('Removing caption %s.', instance.filename)
92 101
93 try { 102 try {
94 await instance.removeCaptionFile() 103 await instance.removeCaptionFile()
95 } catch (err) { 104 } catch (err) {
96 logger.error('Cannot remove caption file of video %s.', instance.Video.uuid) 105 logger.error('Cannot remove caption file %s.', instance.filename)
97 } 106 }
98 } 107 }
99 108
@@ -119,15 +128,28 @@ export class VideoCaptionModel extends Model {
119 return VideoCaptionModel.findOne(query) 128 return VideoCaptionModel.findOne(query)
120 } 129 }
121 130
122 static insertOrReplaceLanguage (videoId: number, language: string, fileUrl: string, transaction: Transaction) { 131 static loadWithVideoByFilename (filename: string): Promise<MVideoCaptionVideo> {
123 const values = { 132 const query = {
124 videoId, 133 where: {
125 language, 134 filename
126 fileUrl 135 },
136 include: [
137 {
138 model: VideoModel.unscoped(),
139 attributes: [ 'id', 'remote', 'uuid' ]
140 }
141 ]
127 } 142 }
128 143
129 return VideoCaptionModel.upsert(values, { transaction, returning: true }) 144 return VideoCaptionModel.findOne(query)
130 .then(([ caption ]) => caption) 145 }
146
147 static async insertOrReplaceLanguage (caption: MVideoCaption, transaction: Transaction) {
148 const existing = await VideoCaptionModel.loadByVideoIdAndLanguage(caption.videoId, caption.language)
149 // Delete existing file
150 if (existing) await existing.destroy({ transaction })
151
152 return caption.save({ transaction })
131 } 153 }
132 154
133 static listVideoCaptions (videoId: number): Promise<MVideoCaptionVideo[]> { 155 static listVideoCaptions (videoId: number): Promise<MVideoCaptionVideo[]> {
@@ -156,6 +178,10 @@ export class VideoCaptionModel extends Model {
156 return VideoCaptionModel.destroy(query) 178 return VideoCaptionModel.destroy(query)
157 } 179 }
158 180
181 static generateCaptionName (language: string) {
182 return `${uuidv4()}-${language}.vtt`
183 }
184
159 isOwned () { 185 isOwned () {
160 return this.Video.remote === false 186 return this.Video.remote === false
161 } 187 }
@@ -170,16 +196,12 @@ export class VideoCaptionModel extends Model {
170 } 196 }
171 } 197 }
172 198
173 getCaptionStaticPath (this: MVideoCaptionFormattable) { 199 getCaptionStaticPath (this: MVideoCaption) {
174 return join(LAZY_STATIC_PATHS.VIDEO_CAPTIONS, this.getCaptionName()) 200 return join(LAZY_STATIC_PATHS.VIDEO_CAPTIONS, this.filename)
175 }
176
177 getCaptionName (this: MVideoCaptionFormattable) {
178 return `${this.Video.uuid}-${this.language}.vtt`
179 } 201 }
180 202
181 removeCaptionFile (this: MVideoCaptionFormattable) { 203 removeCaptionFile (this: MVideoCaption) {
182 return remove(CONFIG.STORAGE.CAPTIONS_DIR + this.getCaptionName()) 204 return remove(CONFIG.STORAGE.CAPTIONS_DIR + this.filename)
183 } 205 }
184 206
185 getFileUrl (video: MVideoAccountLight) { 207 getFileUrl (video: MVideoAccountLight) {
diff --git a/server/models/video/video-playlist.ts b/server/models/video/video-playlist.ts
index 93ecf8cea..9e6ff1f81 100644
--- a/server/models/video/video-playlist.ts
+++ b/server/models/video/video-playlist.ts
@@ -471,7 +471,7 @@ export class VideoPlaylistModel extends Model {
471 generateThumbnailName () { 471 generateThumbnailName () {
472 const extension = '.jpg' 472 const extension = '.jpg'
473 473
474 return 'playlist-' + this.uuid + extension 474 return 'playlist-' + uuidv4() + extension
475 } 475 }
476 476
477 getThumbnailUrl () { 477 getThumbnailUrl () {