aboutsummaryrefslogtreecommitdiffhomepage
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/optimize-old-videos.ts32
-rwxr-xr-xscripts/prune-storage.ts62
-rwxr-xr-xscripts/update-host.ts13
3 files changed, 52 insertions, 55 deletions
diff --git a/scripts/optimize-old-videos.ts b/scripts/optimize-old-videos.ts
index 9692d76ba..bde9d1e01 100644
--- a/scripts/optimize-old-videos.ts
+++ b/scripts/optimize-old-videos.ts
@@ -19,13 +19,13 @@ run()
19 process.exit(-1) 19 process.exit(-1)
20 }) 20 })
21 21
22let currentVideoId = null 22let currentVideoId: string
23let currentFile = null 23let currentFilePath: string
24 24
25process.on('SIGINT', async function () { 25process.on('SIGINT', async function () {
26 console.log('Cleaning up temp files') 26 console.log('Cleaning up temp files')
27 await remove(`${currentFile}_backup`) 27 await remove(`${currentFilePath}_backup`)
28 await remove(`${dirname(currentFile)}/${currentVideoId}-transcoded.mp4`) 28 await remove(`${dirname(currentFilePath)}/${currentVideoId}-transcoded.mp4`)
29 process.exit(0) 29 process.exit(0)
30}) 30})
31 31
@@ -40,12 +40,12 @@ async function run () {
40 currentVideoId = video.id 40 currentVideoId = video.id
41 41
42 for (const file of video.VideoFiles) { 42 for (const file of video.VideoFiles) {
43 currentFile = getVideoFilePath(video, file) 43 currentFilePath = getVideoFilePath(video, file)
44 44
45 const [ videoBitrate, fps, resolution ] = await Promise.all([ 45 const [ videoBitrate, fps, resolution ] = await Promise.all([
46 getVideoFileBitrate(currentFile), 46 getVideoFileBitrate(currentFilePath),
47 getVideoFileFPS(currentFile), 47 getVideoFileFPS(currentFilePath),
48 getVideoFileResolution(currentFile) 48 getVideoFileResolution(currentFilePath)
49 ]) 49 ])
50 50
51 const maxBitrate = getMaxBitrate(resolution.videoFileResolution, fps, VIDEO_TRANSCODING_FPS) 51 const maxBitrate = getMaxBitrate(resolution.videoFileResolution, fps, VIDEO_TRANSCODING_FPS)
@@ -53,25 +53,27 @@ async function run () {
53 if (isMaxBitrateExceeded) { 53 if (isMaxBitrateExceeded) {
54 console.log( 54 console.log(
55 'Optimizing video file %s with bitrate %s kbps (max: %s kbps)', 55 'Optimizing video file %s with bitrate %s kbps (max: %s kbps)',
56 basename(currentFile), videoBitrate / 1000, maxBitrate / 1000 56 basename(currentFilePath), videoBitrate / 1000, maxBitrate / 1000
57 ) 57 )
58 58
59 const backupFile = `${currentFile}_backup` 59 const backupFile = `${currentFilePath}_backup`
60 await copy(currentFile, backupFile) 60 await copy(currentFilePath, backupFile)
61 61
62 await optimizeOriginalVideofile(video, file) 62 await optimizeOriginalVideofile(video, file)
63 // Update file path, the video filename changed
64 currentFilePath = getVideoFilePath(video, file)
63 65
64 const originalDuration = await getDurationFromVideoFile(backupFile) 66 const originalDuration = await getDurationFromVideoFile(backupFile)
65 const newDuration = await getDurationFromVideoFile(currentFile) 67 const newDuration = await getDurationFromVideoFile(currentFilePath)
66 68
67 if (originalDuration === newDuration) { 69 if (originalDuration === newDuration) {
68 console.log('Finished optimizing %s', basename(currentFile)) 70 console.log('Finished optimizing %s', basename(currentFilePath))
69 await remove(backupFile) 71 await remove(backupFile)
70 continue 72 continue
71 } 73 }
72 74
73 console.log('Failed to optimize %s, restoring original', basename(currentFile)) 75 console.log('Failed to optimize %s, restoring original', basename(currentFilePath))
74 await move(backupFile, currentFile, { overwrite: true }) 76 await move(backupFile, currentFilePath, { overwrite: true })
75 await createTorrentAndSetInfoHash(video, file) 77 await createTorrentAndSetInfoHash(video, file)
76 await file.save() 78 await file.save()
77 } 79 }
diff --git a/scripts/prune-storage.ts b/scripts/prune-storage.ts
index 58d24816e..5b029d215 100755
--- a/scripts/prune-storage.ts
+++ b/scripts/prune-storage.ts
@@ -2,11 +2,11 @@ import { registerTSPaths } from '../server/helpers/register-ts-paths'
2registerTSPaths() 2registerTSPaths()
3 3
4import * as prompt from 'prompt' 4import * as prompt from 'prompt'
5import { join } from 'path' 5import { join, basename } from 'path'
6import { CONFIG } from '../server/initializers/config' 6import { CONFIG } from '../server/initializers/config'
7import { VideoModel } from '../server/models/video/video' 7import { VideoModel } from '../server/models/video/video'
8import { initDatabaseModels } from '../server/initializers/database' 8import { initDatabaseModels } from '../server/initializers/database'
9import { readdir, remove } from 'fs-extra' 9import { readdir, remove, stat } from 'fs-extra'
10import { VideoRedundancyModel } from '../server/models/redundancy/video-redundancy' 10import { VideoRedundancyModel } from '../server/models/redundancy/video-redundancy'
11import * as Bluebird from 'bluebird' 11import * as Bluebird from 'bluebird'
12import { getUUIDFromFilename } from '../server/helpers/utils' 12import { getUUIDFromFilename } from '../server/helpers/utils'
@@ -14,6 +14,7 @@ import { ThumbnailModel } from '../server/models/video/thumbnail'
14import { ActorImageModel } from '../server/models/actor/actor-image' 14import { ActorImageModel } from '../server/models/actor/actor-image'
15import { uniq, values } from 'lodash' 15import { uniq, values } from 'lodash'
16import { ThumbnailType } from '@shared/models' 16import { ThumbnailType } from '@shared/models'
17import { VideoFileModel } from '@server/models/video/video-file'
17 18
18run() 19run()
19 .then(() => process.exit(0)) 20 .then(() => process.exit(0))
@@ -37,8 +38,8 @@ async function run () {
37 console.log('Detecting files to remove, it could take a while...') 38 console.log('Detecting files to remove, it could take a while...')
38 39
39 toDelete = toDelete.concat( 40 toDelete = toDelete.concat(
40 await pruneDirectory(CONFIG.STORAGE.VIDEOS_DIR, doesVideoExist(true)), 41 await pruneDirectory(CONFIG.STORAGE.VIDEOS_DIR, doesWebTorrentFileExist()),
41 await pruneDirectory(CONFIG.STORAGE.TORRENTS_DIR, doesVideoExist(true)), 42 await pruneDirectory(CONFIG.STORAGE.TORRENTS_DIR, doesTorrentFileExist()),
42 43
43 await pruneDirectory(CONFIG.STORAGE.REDUNDANCY_DIR, doesRedundancyExist), 44 await pruneDirectory(CONFIG.STORAGE.REDUNDANCY_DIR, doesRedundancyExist),
44 45
@@ -78,26 +79,27 @@ async function pruneDirectory (directory: string, existFun: ExistFun) {
78 79
79 const toDelete: string[] = [] 80 const toDelete: string[] = []
80 await Bluebird.map(files, async file => { 81 await Bluebird.map(files, async file => {
81 if (await existFun(file) !== true) { 82 const filePath = join(directory, file)
82 toDelete.push(join(directory, file)) 83
84 if (await existFun(filePath) !== true) {
85 toDelete.push(filePath)
83 } 86 }
84 }, { concurrency: 20 }) 87 }, { concurrency: 20 })
85 88
86 return toDelete 89 return toDelete
87} 90}
88 91
89function doesVideoExist (keepOnlyOwned: boolean) { 92function doesWebTorrentFileExist () {
90 return async (file: string) => { 93 return (filePath: string) => VideoFileModel.doesOwnedWebTorrentVideoFileExist(basename(filePath))
91 const uuid = getUUIDFromFilename(file) 94}
92 const video = await VideoModel.load(uuid)
93 95
94 return video && (keepOnlyOwned === false || video.isOwned()) 96function doesTorrentFileExist () {
95 } 97 return (filePath: string) => VideoFileModel.doesOwnedTorrentFileExist(basename(filePath))
96} 98}
97 99
98function doesThumbnailExist (keepOnlyOwned: boolean, type: ThumbnailType) { 100function doesThumbnailExist (keepOnlyOwned: boolean, type: ThumbnailType) {
99 return async (file: string) => { 101 return async (filePath: string) => {
100 const thumbnail = await ThumbnailModel.loadByFilename(file, type) 102 const thumbnail = await ThumbnailModel.loadByFilename(basename(filePath), type)
101 if (!thumbnail) return false 103 if (!thumbnail) return false
102 104
103 if (keepOnlyOwned) { 105 if (keepOnlyOwned) {
@@ -109,21 +111,20 @@ function doesThumbnailExist (keepOnlyOwned: boolean, type: ThumbnailType) {
109 } 111 }
110} 112}
111 113
112async function doesActorImageExist (file: string) { 114async function doesActorImageExist (filePath: string) {
113 const image = await ActorImageModel.loadByName(file) 115 const image = await ActorImageModel.loadByName(basename(filePath))
114 116
115 return !!image 117 return !!image
116} 118}
117 119
118async function doesRedundancyExist (file: string) { 120async function doesRedundancyExist (filePath: string) {
119 const uuid = getUUIDFromFilename(file) 121 const isPlaylist = (await stat(filePath)).isDirectory()
120 const video = await VideoModel.loadWithFiles(uuid)
121
122 if (!video) return false
123
124 const isPlaylist = file.includes('.') === false
125 122
126 if (isPlaylist) { 123 if (isPlaylist) {
124 const uuid = getUUIDFromFilename(filePath)
125 const video = await VideoModel.loadWithFiles(uuid)
126 if (!video) return false
127
127 const p = video.getHLSPlaylist() 128 const p = video.getHLSPlaylist()
128 if (!p) return false 129 if (!p) return false
129 130
@@ -131,19 +132,10 @@ async function doesRedundancyExist (file: string) {
131 return !!redundancy 132 return !!redundancy
132 } 133 }
133 134
134 const resolution = parseInt(file.split('-')[5], 10) 135 const file = await VideoFileModel.loadByFilename(basename(filePath))
135 if (isNaN(resolution)) { 136 if (!file) return false
136 console.error('Cannot prune %s because we cannot guess guess the resolution.', file)
137 return true
138 }
139
140 const videoFile = video.getWebTorrentFile(resolution)
141 if (!videoFile) {
142 console.error('Cannot find webtorrent file of video %s - %d', video.url, resolution)
143 return true
144 }
145 137
146 const redundancy = await VideoRedundancyModel.loadLocalByFileId(videoFile.id) 138 const redundancy = await VideoRedundancyModel.loadLocalByFileId(file.id)
147 return !!redundancy 139 return !!redundancy
148} 140}
149 141
diff --git a/scripts/update-host.ts b/scripts/update-host.ts
index 592684225..9e8dd41ca 100755
--- a/scripts/update-host.ts
+++ b/scripts/update-host.ts
@@ -16,7 +16,6 @@ import { VideoShareModel } from '../server/models/video/video-share'
16import { VideoCommentModel } from '../server/models/video/video-comment' 16import { VideoCommentModel } from '../server/models/video/video-comment'
17import { AccountModel } from '../server/models/account/account' 17import { AccountModel } from '../server/models/account/account'
18import { VideoChannelModel } from '../server/models/video/video-channel' 18import { VideoChannelModel } from '../server/models/video/video-channel'
19import { VideoStreamingPlaylistModel } from '../server/models/video/video-streaming-playlist'
20import { initDatabaseModels } from '../server/initializers/database' 19import { initDatabaseModels } from '../server/initializers/database'
21import { createTorrentAndSetInfoHash } from '@server/helpers/webtorrent' 20import { createTorrentAndSetInfoHash } from '@server/helpers/webtorrent'
22import { getServerActor } from '@server/models/application/application' 21import { getServerActor } from '@server/models/application/application'
@@ -128,13 +127,17 @@ async function run () {
128 for (const file of video.VideoFiles) { 127 for (const file of video.VideoFiles) {
129 console.log('Updating torrent file %s of video %s.', file.resolution, video.uuid) 128 console.log('Updating torrent file %s of video %s.', file.resolution, video.uuid)
130 await createTorrentAndSetInfoHash(video, file) 129 await createTorrentAndSetInfoHash(video, file)
130
131 await file.save()
131 } 132 }
132 133
133 for (const playlist of video.VideoStreamingPlaylists) { 134 const playlist = video.getHLSPlaylist()
134 playlist.playlistUrl = WEBSERVER.URL + VideoStreamingPlaylistModel.getHlsMasterPlaylistStaticPath(video.uuid) 135 for (const file of (playlist?.VideoFiles || [])) {
135 playlist.segmentsSha256Url = WEBSERVER.URL + VideoStreamingPlaylistModel.getHlsSha256SegmentsStaticPath(video.uuid, video.isLive) 136 console.log('Updating fragmented torrent file %s of video %s.', file.resolution, video.uuid)
137
138 await createTorrentAndSetInfoHash(video, file)
136 139
137 await playlist.save() 140 await file.save()
138 } 141 }
139 } 142 }
140} 143}