diff --git a/config/production.yaml.example b/config/production.yaml.example
index 987da12cc..f99c8927e 100644
--- a/config/production.yaml.example
+++ b/config/production.yaml.example
@@ -46,3 +46,9 @@ user:
 transcoding:
   enabled: false
   threads: 2
+  resolutions: # Only created if the original video has a higher resolution
+    240p: true
+    360p: true
+    480p: true
+    720p: true
+    1080p: true
diff --git a/server/controllers/api/videos/index.ts b/server/controllers/api/videos/index.ts
index 14c969ec3..2b7ead954 100644
--- a/server/controllers/api/videos/index.ts
+++ b/server/controllers/api/videos/index.ts
@@ -37,10 +37,11 @@ import {
   retryTransactionWrapper,
   generateRandomString,
   getFormattedObjects,
-  renamePromise
+  renamePromise,
+  getVideoFileHeight
 } from '../../../helpers'
 import { TagInstance, VideoInstance } from '../../../models'
-import { VideoCreate, VideoUpdate, VideoResolution } from '../../../../shared'
+import { VideoCreate, VideoUpdate } from '../../../../shared'
 
 import { abuseVideoRouter } from './abuse'
 import { blacklistRouter } from './blacklist'
@@ -192,9 +193,14 @@ function addVideo (req: express.Request, res: express.Response, videoPhysicalFil
         return { author, tagInstances, video }
       })
       .then(({ author, tagInstances, video }) => {
+        const videoFilePath = join(CONFIG.STORAGE.VIDEOS_DIR, videoPhysicalFile.filename)
+        return getVideoFileHeight(videoFilePath)
+          .then(height => ({ author, tagInstances, video, videoFileHeight: height }))
+      })
+      .then(({ author, tagInstances, video, videoFileHeight }) => {
         const videoFileData = {
           extname: extname(videoPhysicalFile.filename),
-          resolution: VideoResolution.ORIGINAL,
+          resolution: videoFileHeight,
           size: videoPhysicalFile.size
         }
 
diff --git a/server/helpers/custom-validators/videos.ts b/server/helpers/custom-validators/videos.ts
index 2eb021ae7..a31aca019 100644
--- a/server/helpers/custom-validators/videos.ts
+++ b/server/helpers/custom-validators/videos.ts
@@ -8,8 +8,7 @@ import {
   VIDEO_CATEGORIES,
   VIDEO_LICENCES,
   VIDEO_LANGUAGES,
-  VIDEO_RATE_TYPES,
-  VIDEO_FILE_RESOLUTIONS
+  VIDEO_RATE_TYPES
 } from '../../initializers'
 import { isUserUsernameValid } from './users'
 import { isArray, exists } from './misc'
@@ -128,7 +127,7 @@ function isVideoFileSizeValid (value: string) {
 }
 
 function isVideoFileResolutionValid (value: string) {
-  return VIDEO_FILE_RESOLUTIONS[value] !== undefined
+  return exists(value) && validator.isInt(value + '')
 }
 
 function isVideoFileExtnameValid (value: string) {
diff --git a/server/helpers/ffmpeg-utils.ts b/server/helpers/ffmpeg-utils.ts
new file mode 100644
index 000000000..c35125ec1
--- /dev/null
+++ b/server/helpers/ffmpeg-utils.ts
@@ -0,0 +1,79 @@
+import * as Promise from 'bluebird'
+import * as ffmpeg from 'fluent-ffmpeg'
+
+import { CONFIG } from '../initializers'
+import { VideoResolution } from '../../shared/models/videos/video-resolution.enum'
+
+function getVideoFileHeight (path: string) {
+  return new Promise<number>((res, rej) => {
+    ffmpeg.ffprobe(path, (err, metadata) => {
+      if (err) return rej(err)
+
+      const videoStream = metadata.streams.find(s => s.codec_type === 'video')
+      return res(videoStream.height)
+    })
+  })
+}
+
+function getDurationFromVideoFile (path: string) {
+  return new Promise<number>((res, rej) => {
+    ffmpeg.ffprobe(path, (err, metadata) => {
+      if (err) return rej(err)
+
+      return res(Math.floor(metadata.format.duration))
+    })
+  })
+}
+
+function generateImageFromVideoFile (fromPath: string, folder: string, imageName: string, size?: string) {
+  const options = {
+    filename: imageName,
+    count: 1,
+    folder
+  }
+
+  if (size !== undefined) {
+    options['size'] = size
+  }
+
+  return new Promise<string>((res, rej) => {
+    ffmpeg(fromPath)
+      .on('error', rej)
+      .on('end', () => res(imageName))
+      .thumbnail(options)
+  })
+}
+
+type TranscodeOptions = {
+  inputPath: string
+  outputPath: string
+  resolution?: VideoResolution
+}
+
+function transcode (options: TranscodeOptions) {
+  return new Promise<void>((res, rej) => {
+    let command = ffmpeg(options.inputPath)
+                    .output(options.outputPath)
+                    .videoCodec('libx264')
+                    .outputOption('-threads ' + CONFIG.TRANSCODING.THREADS)
+                    .outputOption('-movflags faststart')
+
+    if (options.resolution !== undefined) {
+      const size = `${options.resolution}x?` // '720x?' for example
+      command = command.size(size)
+    }
+
+    command.on('error', rej)
+           .on('end', res)
+           .run()
+  })
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+  getVideoFileHeight,
+  getDurationFromVideoFile,
+  generateImageFromVideoFile,
+  transcode
+}
diff --git a/server/helpers/index.ts b/server/helpers/index.ts
index 78215fe10..846bd796f 100644
--- a/server/helpers/index.ts
+++ b/server/helpers/index.ts
@@ -1,6 +1,7 @@
 export * from './core-utils'
 export * from './logger'
 export * from './custom-validators'
+export * from './ffmpeg-utils'
 export * from './database-utils'
 export * from './peertube-crypto'
 export * from './requests'
diff --git a/server/helpers/utils.ts b/server/helpers/utils.ts
index b74442ab0..3317dddc3 100644
--- a/server/helpers/utils.ts
+++ b/server/helpers/utils.ts
@@ -61,7 +61,7 @@ function computeResolutionsToTranscode (videoFileHeight: number) {
   ]
 
   for (const resolution of resolutions) {
-    if (configResolutions[resolution.toString()] === true && videoFileHeight >= resolution) {
+    if (configResolutions[resolution.toString()] === true && videoFileHeight > resolution) {
       resolutionsEnabled.push(resolution)
     }
   }
diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts
index f87041a3f..b11575b34 100644
--- a/server/initializers/constants.ts
+++ b/server/initializers/constants.ts
@@ -189,16 +189,6 @@ const VIDEO_LANGUAGES = {
   14: 'Italian'
 }
 
-// TODO: use VideoResolution when https://github.com/Microsoft/TypeScript/issues/13042 is fixed
-const VIDEO_FILE_RESOLUTIONS: { [ id: number ]: string } = {
-  0: 'original',
-  240: '240p',
-  360: '360p',
-  480: '480p',
-  720: '720p',
-  1080: '1080p'
-}
-
 // ---------------------------------------------------------------------------
 
 // Score a pod has when we create it as a friend
@@ -385,7 +375,6 @@ export {
   THUMBNAILS_SIZE,
   USER_ROLES,
   VIDEO_CATEGORIES,
-  VIDEO_FILE_RESOLUTIONS,
   VIDEO_LANGUAGES,
   VIDEO_LICENCES,
   VIDEO_RATE_TYPES
diff --git a/server/initializers/migrations/0075-video-resolutions.ts b/server/initializers/migrations/0075-video-resolutions.ts
index 6bc1e72ab..e1d9fdacb 100644
--- a/server/initializers/migrations/0075-video-resolutions.ts
+++ b/server/initializers/migrations/0075-video-resolutions.ts
@@ -4,6 +4,7 @@ import { join } from 'path'
 
 import { readdirPromise, renamePromise } from '../../helpers/core-utils'
 import { CONFIG } from '../../initializers/constants'
+import { getVideoFileHeight } from '../../helpers/ffmpeg-utils'
 
 function up (utils: {
   transaction: Sequelize.Transaction,
@@ -14,26 +15,7 @@ function up (utils: {
   const torrentDir = CONFIG.STORAGE.TORRENTS_DIR
   const videoFileDir = CONFIG.STORAGE.VIDEOS_DIR
 
-  return readdirPromise(torrentDir)
-    .then(torrentFiles => {
-      const tasks: Promise<any>[] = []
-      for (const torrentFile of torrentFiles) {
-        const matches = /^([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\.torrent/.exec(torrentFile)
-        if (matches === null) {
-          console.log('Invalid torrent file name %s.', torrentFile)
-          continue
-        }
-
-        const newTorrentName = matches[1] + '-original.torrent'
-        const p = renamePromise(join(torrentDir, torrentFile), join(torrentDir, newTorrentName))
-        tasks.push(p)
-      }
-
-      return Promise.all(tasks)
-    })
-    .then(() => {
-      return readdirPromise(videoFileDir)
-    })
+  return readdirPromise(videoFileDir)
     .then(videoFiles => {
       const tasks: Promise<any>[] = []
       for (const videoFile of videoFiles) {
@@ -43,8 +25,25 @@ function up (utils: {
           continue
         }
 
-        const newVideoFileName = matches[1] + '-original.' + matches[2]
-        const p = renamePromise(join(videoFileDir, videoFile), join(videoFileDir, newVideoFileName))
+        const uuid = matches[1]
+        const ext = matches[2]
+
+        const p = getVideoFileHeight(join(videoFileDir, videoFile))
+          .then(height => {
+            const oldTorrentName = uuid + '.torrent'
+            const newTorrentName = uuid + '-' + height + '.torrent'
+            return renamePromise(join(torrentDir, oldTorrentName), join(torrentDir, newTorrentName)).then(() => height)
+          })
+          .then(height => {
+            const newVideoFileName = uuid + '-' + height + '.' + ext
+            return renamePromise(join(videoFileDir, videoFile), join(videoFileDir, newVideoFileName)).then(() => height)
+          })
+          .then(height => {
+            const query = 'UPDATE "VideoFiles" SET "resolution" = ' + height +
+                          ' WHERE "videoId" = (SELECT "id" FROM "Videos" WHERE "uuid" = \'' + uuid + '\')'
+            return utils.sequelize.query(query)
+          })
+
         tasks.push(p)
       }
 
diff --git a/server/middlewares/validators/videos.ts b/server/middlewares/validators/videos.ts
index bc8b7e541..5f213f974 100644
--- a/server/middlewares/validators/videos.ts
+++ b/server/middlewares/validators/videos.ts
@@ -19,7 +19,8 @@ import {
   isVideoNSFWValid,
   isVideoIdOrUUIDValid,
   isVideoAbuseReasonValid,
-  isVideoRatingTypeValid
+  isVideoRatingTypeValid,
+  getDurationFromVideoFile
 } from '../../helpers'
 import { VideoInstance } from '../../models'
 
@@ -50,7 +51,7 @@ const videosAddValidator = [
             return undefined
           }
 
-          return db.Video.getDurationFromFile(videoFile.path)
+          return getDurationFromVideoFile(videoFile.path)
             .catch(err => {
               logger.error('Invalid input file in videosAddValidator.', err)
               res.status(400)
diff --git a/server/models/user/user.ts b/server/models/user/user.ts
index 7a21dbefa..0dc52d3cf 100644
--- a/server/models/user/user.ts
+++ b/server/models/user/user.ts
@@ -12,7 +12,6 @@ import {
   isUserDisplayNSFWValid,
   isUserVideoQuotaValid
 } from '../../helpers'
-import { VideoResolution } from '../../../shared'
 
 import { addMethodsToModel } from '../utils'
 import {
@@ -243,33 +242,21 @@ loadByUsernameOrEmail = function (username: string, email: string) {
 // ---------------------------------------------------------------------------
 
 function getOriginalVideoFileTotalFromUser (user: UserInstance) {
-  // attributes = [] because we don't want other fields than the sum
-  const query = {
-    where: {
-      resolution: VideoResolution.ORIGINAL
-    },
-    include: [
-      {
-        attributes: [],
-        model: User['sequelize'].models.Video,
-        include: [
-          {
-            attributes: [],
-            model: User['sequelize'].models.Author,
-            include: [
-              {
-                attributes: [],
-                model: User['sequelize'].models.User,
-                where: {
-                  id: user.id
-                }
-              }
-            ]
-          }
-        ]
-      }
-    ]
-  }
+  // Don't use sequelize because we need to use a subquery
+  const query = 'SELECT SUM("size") AS "total" FROM ' +
+                '(SELECT MAX("VideoFiles"."size") AS "size" FROM "VideoFiles" ' +
+                'INNER JOIN "Videos" ON "VideoFiles"."videoId" = "Videos"."id" ' +
+                'INNER JOIN "Authors" ON "Videos"."authorId" = "Authors"."id" ' +
+                'INNER JOIN "Users" ON "Authors"."userId" = "Users"."id" ' +
+                'WHERE "Users"."id" = $userId GROUP BY "Videos"."id") t'
 
-  return User['sequelize'].models.VideoFile.sum('size', query)
+  const options = {
+    bind: { userId: user.id },
+    type: Sequelize.QueryTypes.SELECT
+  }
+  return User['sequelize'].query(query, options).then(([ { total } ]) => {
+    if (total === null) return 0
+
+    return parseInt(total, 10)
+  })
 }
diff --git a/server/models/video/video-interface.ts b/server/models/video/video-interface.ts
index 340426f45..6a3db4f3e 100644
--- a/server/models/video/video-interface.ts
+++ b/server/models/video/video-interface.ts
@@ -35,7 +35,6 @@ export namespace VideoMethods {
 
   // Return thumbnail name
   export type GenerateThumbnailFromData = (video: VideoInstance, thumbnailData: string) => Promise<string>
-  export type GetDurationFromFile = (videoPath: string) => Promise<number>
 
   export type List = () => Promise<VideoInstance[]>
   export type ListOwnedAndPopulateAuthorAndTags = () => Promise<VideoInstance[]>
@@ -65,7 +64,6 @@ export namespace VideoMethods {
 
 export interface VideoClass {
   generateThumbnailFromData: VideoMethods.GenerateThumbnailFromData
-  getDurationFromFile: VideoMethods.GetDurationFromFile
   list: VideoMethods.List
   listForApi: VideoMethods.ListForApi
   listOwnedAndPopulateAuthorAndTags: VideoMethods.ListOwnedAndPopulateAuthorAndTags
diff --git a/server/models/video/video.ts b/server/models/video/video.ts
index c376d769e..2ba6cf25f 100644
--- a/server/models/video/video.ts
+++ b/server/models/video/video.ts
@@ -1,12 +1,12 @@
 import * as safeBuffer from 'safe-buffer'
 const Buffer = safeBuffer.Buffer
-import * as ffmpeg from 'fluent-ffmpeg'
 import * as magnetUtil from 'magnet-uri'
 import { map } from 'lodash'
 import * as parseTorrent from 'parse-torrent'
 import { join } from 'path'
 import * as Sequelize from 'sequelize'
 import * as Promise from 'bluebird'
+import { maxBy } from 'lodash'
 
 import { TagInstance } from './tag-interface'
 import {
@@ -23,7 +23,10 @@ import {
   renamePromise,
   writeFilePromise,
   createTorrentPromise,
-  statPromise
+  statPromise,
+  generateImageFromVideoFile,
+  transcode,
+  getVideoFileHeight
 } from '../../helpers'
 import {
   CONFIG,
@@ -32,8 +35,7 @@ import {
   VIDEO_CATEGORIES,
   VIDEO_LICENCES,
   VIDEO_LANGUAGES,
-  THUMBNAILS_SIZE,
-  VIDEO_FILE_RESOLUTIONS
+  THUMBNAILS_SIZE
 } from '../../initializers'
 import { removeVideoToFriends } from '../../lib'
 import { VideoResolution } from '../../../shared'
@@ -67,7 +69,6 @@ let createTorrentAndSetInfoHash: VideoMethods.CreateTorrentAndSetInfoHash
 let getOriginalFileHeight: VideoMethods.GetOriginalFileHeight
 
 let generateThumbnailFromData: VideoMethods.GenerateThumbnailFromData
-let getDurationFromFile: VideoMethods.GetDurationFromFile
 let list: VideoMethods.List
 let listForApi: VideoMethods.ListForApi
 let loadByHostAndUUID: VideoMethods.LoadByHostAndUUID
@@ -233,7 +234,6 @@ export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.Da
     associate,
 
     generateThumbnailFromData,
-    getDurationFromFile,
     list,
     listForApi,
     listOwnedAndPopulateAuthorAndTags,
@@ -338,11 +338,12 @@ function afterDestroy (video: VideoInstance, options: { transaction: Sequelize.T
 getOriginalFile = function (this: VideoInstance) {
   if (Array.isArray(this.VideoFiles) === false) return undefined
 
-  return this.VideoFiles.find(file => file.resolution === VideoResolution.ORIGINAL)
+  // The original file is the file that have the higher resolution
+  return maxBy(this.VideoFiles, file => file.resolution)
 }
 
 getVideoFilename = function (this: VideoInstance, videoFile: VideoFileInstance) {
-  return this.uuid + '-' + VIDEO_FILE_RESOLUTIONS[videoFile.resolution] + videoFile.extname
+  return this.uuid + '-' + videoFile.resolution + videoFile.extname
 }
 
 getThumbnailName = function (this: VideoInstance) {
@@ -358,7 +359,7 @@ getPreviewName = function (this: VideoInstance) {
 
 getTorrentFileName = function (this: VideoInstance, videoFile: VideoFileInstance) {
   const extension = '.torrent'
-  return this.uuid + '-' + VIDEO_FILE_RESOLUTIONS[videoFile.resolution] + extension
+  return this.uuid + '-' + videoFile.resolution + extension
 }
 
 isOwned = function (this: VideoInstance) {
@@ -366,11 +367,20 @@ isOwned = function (this: VideoInstance) {
 }
 
 createPreview = function (this: VideoInstance, videoFile: VideoFileInstance) {
-  return generateImage(this, this.getVideoFilePath(videoFile), CONFIG.STORAGE.PREVIEWS_DIR, this.getPreviewName(), null)
+  return generateImageFromVideoFile(
+    this.getVideoFilePath(videoFile),
+    CONFIG.STORAGE.PREVIEWS_DIR,
+    this.getPreviewName()
+  )
 }
 
 createThumbnail = function (this: VideoInstance, videoFile: VideoFileInstance) {
-  return generateImage(this, this.getVideoFilePath(videoFile), CONFIG.STORAGE.THUMBNAILS_DIR, this.getThumbnailName(), THUMBNAILS_SIZE)
+  return generateImageFromVideoFile(
+    this.getVideoFilePath(videoFile),
+    CONFIG.STORAGE.THUMBNAILS_DIR,
+    this.getThumbnailName(),
+    THUMBNAILS_SIZE
+  )
 }
 
 getVideoFilePath = function (this: VideoInstance, videoFile: VideoFileInstance) {
@@ -480,8 +490,7 @@ toFormattedJSON = function (this: VideoInstance) {
   // Format and sort video files
   json.files = this.VideoFiles
                    .map(videoFile => {
-                     let resolutionLabel = VIDEO_FILE_RESOLUTIONS[videoFile.resolution]
-                     if (!resolutionLabel) resolutionLabel = 'Unknown'
+                     let resolutionLabel = videoFile.resolution + 'p'
 
                      const videoFileJson = {
                        resolution: videoFile.resolution,
@@ -578,46 +587,42 @@ optimizeOriginalVideofile = function (this: VideoInstance) {
   const videoInputPath = join(videosDirectory, this.getVideoFilename(inputVideoFile))
   const videoOutputPath = join(videosDirectory, this.id + '-transcoded' + newExtname)
 
-  return new Promise<void>((res, rej) => {
-    ffmpeg(videoInputPath)
-      .output(videoOutputPath)
-      .videoCodec('libx264')
-      .outputOption('-threads ' + CONFIG.TRANSCODING.THREADS)
-      .outputOption('-movflags faststart')
-      .on('error', rej)
-      .on('end', () => {
+  const transcodeOptions = {
+    inputPath: videoInputPath,
+    outputPath: videoOutputPath
+  }
 
-        return unlinkPromise(videoInputPath)
-          .then(() => {
-            // Important to do this before getVideoFilename() to take in account the new file extension
-            inputVideoFile.set('extname', newExtname)
+  return transcode(transcodeOptions)
+    .then(() => {
+      return unlinkPromise(videoInputPath)
+    })
+    .then(() => {
+      // Important to do this before getVideoFilename() to take in account the new file extension
+      inputVideoFile.set('extname', newExtname)
 
-            return renamePromise(videoOutputPath, this.getVideoFilePath(inputVideoFile))
-          })
-          .then(() => {
-            return statPromise(this.getVideoFilePath(inputVideoFile))
-          })
-          .then(stats => {
-            return inputVideoFile.set('size', stats.size)
-          })
-          .then(() => {
-            return this.createTorrentAndSetInfoHash(inputVideoFile)
-          })
-          .then(() => {
-            return inputVideoFile.save()
-          })
-          .then(() => {
-            return res()
-          })
-          .catch(err => {
-            // Auto destruction...
-            this.destroy().catch(err => logger.error('Cannot destruct video after transcoding failure.', err))
+      return renamePromise(videoOutputPath, this.getVideoFilePath(inputVideoFile))
+    })
+    .then(() => {
+      return statPromise(this.getVideoFilePath(inputVideoFile))
+    })
+    .then(stats => {
+      return inputVideoFile.set('size', stats.size)
+    })
+    .then(() => {
+      return this.createTorrentAndSetInfoHash(inputVideoFile)
+    })
+    .then(() => {
+      return inputVideoFile.save()
+    })
+    .then(() => {
+      return undefined
+    })
+    .catch(err => {
+      // Auto destruction...
+      this.destroy().catch(err => logger.error('Cannot destruct video after transcoding failure.', err))
 
-            return rej(err)
-          })
-      })
-      .run()
-  })
+      throw err
+    })
 }
 
 transcodeOriginalVideofile = function (this: VideoInstance, resolution: VideoResolution) {
@@ -634,52 +639,37 @@ transcodeOriginalVideofile = function (this: VideoInstance, resolution: VideoRes
     videoId: this.id
   })
   const videoOutputPath = join(videosDirectory, this.getVideoFilename(newVideoFile))
-  const resolutionOption = `${resolution}x?` // '720x?' for example
 
-  return new Promise<void>((res, rej) => {
-    ffmpeg(videoInputPath)
-      .output(videoOutputPath)
-      .videoCodec('libx264')
-      .size(resolutionOption)
-      .outputOption('-threads ' + CONFIG.TRANSCODING.THREADS)
-      .outputOption('-movflags faststart')
-      .on('error', rej)
-      .on('end', () => {
-        return statPromise(videoOutputPath)
-          .then(stats => {
-            newVideoFile.set('size', stats.size)
+  const transcodeOptions = {
+    inputPath: videoInputPath,
+    outputPath: videoOutputPath,
+    resolution
+  }
+  return transcode(transcodeOptions)
+    .then(() => {
+      return statPromise(videoOutputPath)
+    })
+    .then(stats => {
+      newVideoFile.set('size', stats.size)
 
-            return undefined
-          })
-          .then(() => {
-            return this.createTorrentAndSetInfoHash(newVideoFile)
-          })
-          .then(() => {
-            return newVideoFile.save()
-          })
-          .then(() => {
-            return this.VideoFiles.push(newVideoFile)
-          })
-          .then(() => {
-            return res()
-          })
-          .catch(rej)
-      })
-      .run()
-  })
+      return undefined
+    })
+    .then(() => {
+      return this.createTorrentAndSetInfoHash(newVideoFile)
+    })
+    .then(() => {
+      return newVideoFile.save()
+    })
+    .then(() => {
+      return this.VideoFiles.push(newVideoFile)
+    })
+    .then(() => undefined)
 }
 
 getOriginalFileHeight = function (this: VideoInstance) {
   const originalFilePath = this.getVideoFilePath(this.getOriginalFile())
 
-  return new Promise<number>((res, rej) => {
-    ffmpeg.ffprobe(originalFilePath, (err, metadata) => {
-      if (err) return rej(err)
-
-      const videoStream = metadata.streams.find(s => s.codec_type === 'video')
-      return res(videoStream.height)
-    })
-  })
+  return getVideoFileHeight(originalFilePath)
 }
 
 removeThumbnail = function (this: VideoInstance) {
@@ -714,16 +704,6 @@ generateThumbnailFromData = function (video: VideoInstance, thumbnailData: strin
   })
 }
 
-getDurationFromFile = function (videoPath: string) {
-  return new Promise<number>((res, rej) => {
-    ffmpeg.ffprobe(videoPath, (err, metadata) => {
-      if (err) return rej(err)
-
-      return res(Math.floor(metadata.format.duration))
-    })
-  })
-}
-
 list = function () {
   const query = {
     include: [ Video['sequelize'].models.VideoFile ]
@@ -964,22 +944,3 @@ function createBaseVideosWhere () {
     }
   }
 }
-
-function generateImage (video: VideoInstance, videoPath: string, folder: string, imageName: string, size: string) {
-  const options = {
-    filename: imageName,
-    count: 1,
-    folder
-  }
-
-  if (size) {
-    options['size'] = size
-  }
-
-  return new Promise<string>((res, rej) => {
-    ffmpeg(videoPath)
-      .on('error', rej)
-      .on('end', () => res(imageName))
-      .thumbnail(options)
-  })
-}
diff --git a/server/tests/api/multiple-pods.ts b/server/tests/api/multiple-pods.ts
index 08fa73aa2..8b60ac0f4 100644
--- a/server/tests/api/multiple-pods.ts
+++ b/server/tests/api/multiple-pods.ts
@@ -106,8 +106,8 @@ describe('Test multiple pods', function () {
         const file = video.files[0]
         const magnetUri = file.magnetUri
         expect(file.magnetUri).to.have.lengthOf.above(2)
-        expect(file.resolution).to.equal(0)
-        expect(file.resolutionLabel).to.equal('original')
+        expect(file.resolution).to.equal(720)
+        expect(file.resolutionLabel).to.equal('720p')
         expect(file.size).to.equal(572456)
 
         if (server.url !== 'http://localhost:9001') {
@@ -172,7 +172,7 @@ describe('Test multiple pods', function () {
         expect(dateIsValid(video.updatedAt)).to.be.true
         expect(video.author).to.equal('root')
 
-        expect(video.files).to.have.lengthOf(5)
+        expect(video.files).to.have.lengthOf(4)
 
         // Check common attributes
         for (const file of video.files) {
@@ -192,11 +192,6 @@ describe('Test multiple pods', function () {
           }
         }
 
-        const originalFile = video.files.find(f => f.resolution === 0)
-        expect(originalFile).not.to.be.undefined
-        expect(originalFile.resolutionLabel).to.equal('original')
-        expect(originalFile.size).to.be.above(700000).and.below(720000)
-
         const file240p = video.files.find(f => f.resolution === 240)
         expect(file240p).not.to.be.undefined
         expect(file240p.resolutionLabel).to.equal('240p')
@@ -215,7 +210,7 @@ describe('Test multiple pods', function () {
         const file720p = video.files.find(f => f.resolution === 720)
         expect(file720p).not.to.be.undefined
         expect(file720p.resolutionLabel).to.equal('720p')
-        expect(file720p.size).to.be.above(310000).and.below(320000)
+        expect(file720p.size).to.be.above(700000).and.below(7200000)
 
         const test = await testVideoImage(server.url, 'video_short2.webm', video.thumbnailPath)
         expect(test).to.equal(true)
@@ -291,8 +286,8 @@ describe('Test multiple pods', function () {
 
         const file1 = video1.files[0]
         expect(file1.magnetUri).to.have.lengthOf.above(2)
-        expect(file1.resolution).to.equal(0)
-        expect(file1.resolutionLabel).to.equal('original')
+        expect(file1.resolution).to.equal(720)
+        expect(file1.resolutionLabel).to.equal('720p')
         expect(file1.size).to.equal(292677)
 
         expect(video2.name).to.equal('my super name for pod 3-2')
@@ -316,8 +311,8 @@ describe('Test multiple pods', function () {
         const file2 = video2.files[0]
         const magnetUri2 = file2.magnetUri
         expect(file2.magnetUri).to.have.lengthOf.above(2)
-        expect(file2.resolution).to.equal(0)
-        expect(file2.resolutionLabel).to.equal('original')
+        expect(file2.resolution).to.equal(720)
+        expect(file2.resolutionLabel).to.equal('720p')
         expect(file2.size).to.equal(218910)
 
         if (server.url !== 'http://localhost:9003') {
@@ -402,6 +397,22 @@ describe('Test multiple pods', function () {
       expect(torrent.files.length).to.equal(1)
       expect(torrent.files[0].path).to.exist.and.to.not.equal('')
     })
+
+    it('Should add the file 2 in 360p by asking pod 1', async function () {
+      // Yes, this could be long
+      this.timeout(200000)
+
+      const res = await getVideosList(servers[0].url)
+
+      const video = res.body.data.find(v => v.name === 'my super name for pod 2')
+      const file = video.files.find(f => f.resolution === 360)
+      expect(file).not.to.be.undefined
+
+      const torrent = await webtorrentAdd(file.magnetUri)
+      expect(torrent.files).to.be.an('array')
+      expect(torrent.files.length).to.equal(1)
+      expect(torrent.files[0].path).to.exist.and.to.not.equal('')
+    })
   })
 
   describe('Should update video views, likes and dislikes', function () {
@@ -562,8 +573,8 @@ describe('Test multiple pods', function () {
 
         const file = videoUpdated.files[0]
         expect(file.magnetUri).to.have.lengthOf.above(2)
-        expect(file.resolution).to.equal(0)
-        expect(file.resolutionLabel).to.equal('original')
+        expect(file.resolution).to.equal(720)
+        expect(file.resolutionLabel).to.equal('720p')
         expect(file.size).to.equal(292677)
 
         const test = await testVideoImage(server.url, 'video_short3.webm', videoUpdated.thumbnailPath)
diff --git a/server/tests/api/single-pod.ts b/server/tests/api/single-pod.ts
index 83c981f9b..82bc51a3e 100644
--- a/server/tests/api/single-pod.ts
+++ b/server/tests/api/single-pod.ts
@@ -127,8 +127,8 @@ describe('Test a single pod', function () {
     const file = video.files[0]
     const magnetUri = file.magnetUri
     expect(file.magnetUri).to.have.lengthOf.above(2)
-    expect(file.resolution).to.equal(0)
-    expect(file.resolutionLabel).to.equal('original')
+    expect(file.resolution).to.equal(720)
+    expect(file.resolutionLabel).to.equal('720p')
     expect(file.size).to.equal(218910)
 
     const test = await testVideoImage(server.url, 'video_short.webm', video.thumbnailPath)
@@ -170,8 +170,8 @@ describe('Test a single pod', function () {
 
     const file = video.files[0]
     expect(file.magnetUri).to.have.lengthOf.above(2)
-    expect(file.resolution).to.equal(0)
-    expect(file.resolutionLabel).to.equal('original')
+    expect(file.resolution).to.equal(720)
+    expect(file.resolutionLabel).to.equal('720p')
     expect(file.size).to.equal(218910)
 
     const test = await testVideoImage(server.url, 'video_short.webm', video.thumbnailPath)
@@ -229,8 +229,8 @@ describe('Test a single pod', function () {
 
     const file = video.files[0]
     expect(file.magnetUri).to.have.lengthOf.above(2)
-    expect(file.resolution).to.equal(0)
-    expect(file.resolutionLabel).to.equal('original')
+    expect(file.resolution).to.equal(720)
+    expect(file.resolutionLabel).to.equal('720p')
     expect(file.size).to.equal(218910)
 
     const test = await testVideoImage(server.url, 'video_short.webm', video.thumbnailPath)
@@ -291,8 +291,8 @@ describe('Test a single pod', function () {
 
     const file = video.files[0]
     expect(file.magnetUri).to.have.lengthOf.above(2)
-    expect(file.resolution).to.equal(0)
-    expect(file.resolutionLabel).to.equal('original')
+    expect(file.resolution).to.equal(720)
+    expect(file.resolutionLabel).to.equal('720p')
     expect(file.size).to.equal(218910)
 
     const test = await testVideoImage(server.url, 'video_short.webm', video.thumbnailPath)
@@ -569,8 +569,8 @@ describe('Test a single pod', function () {
     const file = video.files[0]
     const magnetUri = file.magnetUri
     expect(file.magnetUri).to.have.lengthOf.above(2)
-    expect(file.resolution).to.equal(0)
-    expect(file.resolutionLabel).to.equal('original')
+    expect(file.resolution).to.equal(720)
+    expect(file.resolutionLabel).to.equal('720p')
     expect(file.size).to.equal(292677)
 
     const test = await testVideoImage(server.url, 'video_short3.webm', video.thumbnailPath)
@@ -612,8 +612,8 @@ describe('Test a single pod', function () {
 
     const file = video.files[0]
     expect(file.magnetUri).to.have.lengthOf.above(2)
-    expect(file.resolution).to.equal(0)
-    expect(file.resolutionLabel).to.equal('original')
+    expect(file.resolution).to.equal(720)
+    expect(file.resolutionLabel).to.equal('720p')
     expect(file.size).to.equal(292677)
   })
 
@@ -647,8 +647,8 @@ describe('Test a single pod', function () {
 
     const file = video.files[0]
     expect(file.magnetUri).to.have.lengthOf.above(2)
-    expect(file.resolution).to.equal(0)
-    expect(file.resolutionLabel).to.equal('original')
+    expect(file.resolution).to.equal(720)
+    expect(file.resolutionLabel).to.equal('720p')
     expect(file.size).to.equal(292677)
   })
 
diff --git a/server/tests/api/video-transcoder.ts b/server/tests/api/video-transcoder.ts
index b5d84d9e7..22d89724b 100644
--- a/server/tests/api/video-transcoder.ts
+++ b/server/tests/api/video-transcoder.ts
@@ -68,7 +68,7 @@ describe('Test video transcoding', function () {
     const res = await getVideosList(servers[1].url)
 
     const video = res.body.data[0]
-    expect(video.files).to.have.lengthOf(5)
+    expect(video.files).to.have.lengthOf(4)
 
     const magnetUri = video.files[0].magnetUri
     expect(magnetUri).to.match(/\.mp4/)
diff --git a/server/tests/cli/update-host.ts b/server/tests/cli/update-host.ts
index e31a84156..7e1d3f658 100644
--- a/server/tests/cli/update-host.ts
+++ b/server/tests/cli/update-host.ts
@@ -55,13 +55,13 @@ describe('Test update host scripts', function () {
     expect(videos).to.have.lengthOf(2)
 
     for (const video of videos) {
-      expect(video.files).to.have.lengthOf(5)
+      expect(video.files).to.have.lengthOf(4)
 
       for (const file of video.files) {
         expect(file.magnetUri).to.contain('localhost%3A9002%2Ftracker%2Fsocket')
         expect(file.magnetUri).to.contain('localhost%3A9002%2Fstatic%2Fwebseed%2F')
 
-        const torrent = await parseTorrentVideo(server, video.uuid, file.resolutionLabel)
+        const torrent = await parseTorrentVideo(server, video.uuid, file.resolution)
         expect(torrent.announce[0]).to.equal('ws://localhost:9002/tracker/socket')
         expect(torrent.urlList[0]).to.contain('http://localhost:9002/static/webseed')
       }
diff --git a/server/tests/utils/videos.ts b/server/tests/utils/videos.ts
index 7f8bd39c0..2a9a236ca 100644
--- a/server/tests/utils/videos.ts
+++ b/server/tests/utils/videos.ts
@@ -196,14 +196,14 @@ function uploadVideo (url: string, accessToken: string, videoAttributesArg: Vide
     req.field('tags[' + i + ']', attributes.tags[i])
   }
 
-  let filepath = ''
+  let filePath = ''
   if (isAbsolute(attributes.fixture)) {
-    filepath = attributes.fixture
+    filePath = attributes.fixture
   } else {
-    filepath = join(__dirname, '..', 'api', 'fixtures', attributes.fixture)
+    filePath = join(__dirname, '..', 'api', 'fixtures', attributes.fixture)
   }
 
-  return req.attach('videofile', filepath)
+  return req.attach('videofile', filePath)
             .expect(specialStatus)
 }
 
@@ -238,9 +238,9 @@ function rateVideo (url: string, accessToken: string, id: number, rating: string
           .expect(specialStatus)
 }
 
-function parseTorrentVideo (server: ServerInfo, videoUUID: string, resolutionLabel: string) {
+function parseTorrentVideo (server: ServerInfo, videoUUID: string, resolution: number) {
   return new Promise<any>((res, rej) => {
-    const torrentName = videoUUID + '-' + resolutionLabel + '.torrent'
+    const torrentName = videoUUID + '-' + resolution + '.torrent'
     const torrentPath = join(__dirname, '..', '..', '..', 'test' + server.serverNumber, 'torrents', torrentName)
     readFile(torrentPath, (err, data) => {
       if (err) return rej(err)
diff --git a/shared/models/videos/video-resolution.enum.ts b/shared/models/videos/video-resolution.enum.ts
index bdce77ed6..100fc0e6e 100644
--- a/shared/models/videos/video-resolution.enum.ts
+++ b/shared/models/videos/video-resolution.enum.ts
@@ -1,5 +1,4 @@
 export enum VideoResolution {
-  ORIGINAL = 0,
   H_240P = 240,
   H_360P = 360,
   H_480P = 480,