diff --git a/.gitignore b/.gitignore
index 3a91facb4..fbf8fdf3c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -37,6 +37,8 @@
 /scripts/i18n/generate-iso639-target.ts
 
 # Other
+/dump.rdb
+/.theia/
 /profiling/
 /*.zip
 /*.tar.xz
diff --git a/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.html b/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.html
index a11238925..06fd9833a 100644
--- a/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.html
+++ b/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.html
@@ -47,6 +47,11 @@
       inputName="autoPlayVideo" formControlName="autoPlayVideo"
       i18n-labelText labelText="Automatically plays video"
     ></my-peertube-checkbox>
+
+    <my-peertube-checkbox
+      inputName="autoPlayNextVideo" formControlName="autoPlayNextVideo"
+      i18n-labelText labelText="Automatically starts playing next video"
+    ></my-peertube-checkbox>
   </div>
 
   <input type="submit" i18n-value value="Save" [disabled]="!form.valid">
diff --git a/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.ts b/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.ts
index 4fb828082..99eee23b8 100644
--- a/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.ts
+++ b/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.ts
@@ -36,6 +36,7 @@ export class MyAccountVideoSettingsComponent extends FormReactive implements OnI
       nsfwPolicy: null,
       webTorrentEnabled: null,
       autoPlayVideo: null,
+      autoPlayNextVideo: null,
       videoLanguages: null
     })
 
@@ -57,6 +58,7 @@ export class MyAccountVideoSettingsComponent extends FormReactive implements OnI
         nsfwPolicy: this.user.nsfwPolicy,
         webTorrentEnabled: this.user.webTorrentEnabled,
         autoPlayVideo: this.user.autoPlayVideo === true,
+        autoPlayNextVideo: this.user.autoPlayNextVideo,
         videoLanguages
       })
     })
@@ -66,6 +68,7 @@ export class MyAccountVideoSettingsComponent extends FormReactive implements OnI
     const nsfwPolicy = this.form.value[ 'nsfwPolicy' ]
     const webTorrentEnabled = this.form.value['webTorrentEnabled']
     const autoPlayVideo = this.form.value['autoPlayVideo']
+    const autoPlayNextVideo = this.form.value['autoPlayNextVideo']
 
     let videoLanguages: string[] = this.form.value['videoLanguages']
     if (Array.isArray(videoLanguages)) {
@@ -84,6 +87,7 @@ export class MyAccountVideoSettingsComponent extends FormReactive implements OnI
       nsfwPolicy,
       webTorrentEnabled,
       autoPlayVideo,
+      autoPlayNextVideo,
       videoLanguages
     }
 
diff --git a/client/src/app/shared/users/user.model.ts b/client/src/app/shared/users/user.model.ts
index 656b73dd2..e0b3f1faf 100644
--- a/client/src/app/shared/users/user.model.ts
+++ b/client/src/app/shared/users/user.model.ts
@@ -16,6 +16,7 @@ export class User implements UserServerModel {
   adminFlags?: UserAdminFlag
 
   autoPlayVideo: boolean
+  autoPlayNextVideo: boolean
   webTorrentEnabled: boolean
   videosHistoryEnabled: boolean
   videoLanguages: string[]
diff --git a/client/src/app/videos/+video-watch/video-watch.component.html b/client/src/app/videos/+video-watch/video-watch.component.html
index 6a02f630a..cd60c407f 100644
--- a/client/src/app/videos/+video-watch/video-watch.component.html
+++ b/client/src/app/videos/+video-watch/video-watch.component.html
@@ -199,7 +199,11 @@
       <my-video-comments [video]="video" [user]="user"></my-video-comments>
     </div>
 
-    <my-recommended-videos [inputRecommendation]="{ uuid: video.uuid, tags: video.tags }" [user]="user"></my-recommended-videos>
+    <my-recommended-videos
+        [inputRecommendation]="{ uuid: video.uuid, tags: video.tags }"
+        [user]="user"
+        (gotRecommendations)="onRecommendations($event)"
+    ></my-recommended-videos>
   </div>
 
   <div class="row privacy-concerns" *ngIf="hasAlreadyAcceptedPrivacyConcern === false">
diff --git a/client/src/app/videos/+video-watch/video-watch.component.ts b/client/src/app/videos/+video-watch/video-watch.component.ts
index 21a24113f..1e7991738 100644
--- a/client/src/app/videos/+video-watch/video-watch.component.ts
+++ b/client/src/app/videos/+video-watch/video-watch.component.ts
@@ -35,6 +35,7 @@ import { getStoredTheater } from '../../../assets/player/peertube-player-local-s
 import { PluginService } from '@app/core/plugins/plugin.service'
 import { HooksService } from '@app/core/plugins/hooks.service'
 import { PlatformLocation } from '@angular/common'
+import { randomInt } from '@shared/core-utils/miscs/miscs'
 
 @Component({
   selector: 'my-video-watch',
@@ -69,6 +70,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
   remoteServerDown = false
   hotkeys: Hotkey[]
 
+  private nextVideoUuid = ''
   private currentTime: number
   private paramsSub: Subscription
   private queryParamsSub: Subscription
@@ -217,6 +219,13 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
     return this.video.tags
   }
 
+  onRecommendations (videos: Video[]) {
+    if (videos.length > 0) {
+      // Pick a random video until the recommendations are improved
+      this.nextVideoUuid = videos[randomInt(0,videos.length - 1)].uuid
+    }
+  }
+
   onVideoRemoved () {
     this.redirectService.redirectToHomepage()
   }
@@ -477,6 +486,8 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
       this.player.one('ended', () => {
         if (this.playlist) {
           this.zone.run(() => this.videoWatchPlaylist.navigateToNextPlaylistVideo())
+        } else if (this.user && this.user.autoPlayNextVideo) {
+          this.zone.run(() => this.autoplayNext())
         }
       })
 
@@ -500,6 +511,12 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
     this.hooks.runAction('action:video-watch.video.loaded', 'video-watch')
   }
 
+  private autoplayNext () {
+    if (this.nextVideoUuid) {
+      this.router.navigate([ '/videos/watch', this.nextVideoUuid ])
+    }
+  }
+
   private setRating (nextRating: UserVideoRateType) {
     const ratingMethods: { [id in UserVideoRateType]: (id: number) => Observable<any> } = {
       like: this.videoService.setVideoLike,
diff --git a/client/src/app/videos/recommendations/recommended-videos.component.ts b/client/src/app/videos/recommendations/recommended-videos.component.ts
index 68fd750cc..7e0fb8856 100644
--- a/client/src/app/videos/recommendations/recommended-videos.component.ts
+++ b/client/src/app/videos/recommendations/recommended-videos.component.ts
@@ -1,4 +1,4 @@
-import { Component, Input, OnChanges } from '@angular/core'
+import { Component, Input, Output, OnChanges, EventEmitter } from '@angular/core'
 import { Observable } from 'rxjs'
 import { Video } from '@app/shared/video/video.model'
 import { RecommendationInfo } from '@app/shared/video/recommendation-info.model'
@@ -12,6 +12,7 @@ import { User } from '@app/shared'
 export class RecommendedVideosComponent implements OnChanges {
   @Input() inputRecommendation: RecommendationInfo
   @Input() user: User
+  @Output() gotRecommendations = new EventEmitter<Video[]>()
 
   readonly hasVideos$: Observable<boolean>
   readonly videos$: Observable<Video[]>
@@ -21,6 +22,7 @@ export class RecommendedVideosComponent implements OnChanges {
   ) {
     this.videos$ = this.store.recommendations$
     this.hasVideos$ = this.store.hasRecommendations$
+    this.videos$.subscribe(videos => this.gotRecommendations.emit(videos))
   }
 
   public ngOnChanges (): void {
diff --git a/server/controllers/api/users/me.ts b/server/controllers/api/users/me.ts
index bf872ca52..cfc346c35 100644
--- a/server/controllers/api/users/me.ts
+++ b/server/controllers/api/users/me.ts
@@ -175,6 +175,7 @@ async function updateMe (req: express.Request, res: express.Response) {
   if (body.nsfwPolicy !== undefined) user.nsfwPolicy = body.nsfwPolicy
   if (body.webTorrentEnabled !== undefined) user.webTorrentEnabled = body.webTorrentEnabled
   if (body.autoPlayVideo !== undefined) user.autoPlayVideo = body.autoPlayVideo
+  if (body.autoPlayNextVideo !== undefined) user.autoPlayNextVideo = body.autoPlayNextVideo
   if (body.videosHistoryEnabled !== undefined) user.videosHistoryEnabled = body.videosHistoryEnabled
   if (body.videoLanguages !== undefined) user.videoLanguages = body.videoLanguages
   if (body.theme !== undefined) user.theme = body.theme
diff --git a/server/helpers/custom-validators/users.ts b/server/helpers/custom-validators/users.ts
index 68e84d9eb..16a95f120 100644
--- a/server/helpers/custom-validators/users.ts
+++ b/server/helpers/custom-validators/users.ts
@@ -65,6 +65,10 @@ function isUserBlockedValid (value: any) {
   return isBooleanValid(value)
 }
 
+function isUserAutoPlayNextVideoValid (value: any) {
+  return isBooleanValid(value)
+}
+
 function isNoInstanceConfigWarningModal (value: any) {
   return isBooleanValid(value)
 }
@@ -106,6 +110,7 @@ export {
   isUserNSFWPolicyValid,
   isUserWebTorrentEnabledValid,
   isUserAutoPlayVideoValid,
+  isUserAutoPlayNextVideoValid,
   isUserDisplayNameValid,
   isUserDescriptionValid,
   isNoInstanceConfigWarningModal,
diff --git a/server/models/account/user.ts b/server/models/account/user.ts
index 451e1fd6b..38c6d474a 100644
--- a/server/models/account/user.ts
+++ b/server/models/account/user.ts
@@ -25,6 +25,7 @@ import {
   isNoInstanceConfigWarningModal,
   isUserAdminFlagsValid,
   isUserAutoPlayVideoValid,
+  isUserAutoPlayNextVideoValid,
   isUserBlockedReasonValid,
   isUserBlockedValid,
   isUserEmailVerifiedValid,
@@ -160,6 +161,12 @@ export class UserModel extends Model<UserModel> {
   @Column
   autoPlayVideo: boolean
 
+  @AllowNull(false)
+  @Default(false)
+  @Is('UserAutoPlayNextVideo', value => throwIfNotValid(value, isUserAutoPlayNextVideoValid, 'auto play next video boolean'))
+  @Column
+  autoPlayNextVideo: boolean
+
   @AllowNull(true)
   @Default(null)
   @Is('UserVideoLanguages', value => throwIfNotValid(value, isUserVideoLanguages, 'video languages'))
@@ -597,6 +604,7 @@ export class UserModel extends Model<UserModel> {
       webTorrentEnabled: this.webTorrentEnabled,
       videosHistoryEnabled: this.videosHistoryEnabled,
       autoPlayVideo: this.autoPlayVideo,
+      autoPlayNextVideo: this.autoPlayNextVideo,
       videoLanguages: this.videoLanguages,
 
       role: this.role,
diff --git a/server/tests/api/check-params/users.ts b/server/tests/api/check-params/users.ts
index 9d7ff8984..5d5af284c 100644
--- a/server/tests/api/check-params/users.ts
+++ b/server/tests/api/check-params/users.ts
@@ -418,6 +418,14 @@ describe('Test users API validators', function () {
       await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
     })
 
+    it('Should fail with an invalid autoPlayNextVideo attribute', async function () {
+      const fields = {
+        autoPlayNextVideo: -1
+      }
+
+      await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
+    })
+
     it('Should fail with an invalid videosHistoryEnabled attribute', async function () {
       const fields = {
         videosHistoryEnabled: -1
diff --git a/server/tests/api/users/users.ts b/server/tests/api/users/users.ts
index 95b1bb626..ca06942e7 100644
--- a/server/tests/api/users/users.ts
+++ b/server/tests/api/users/users.ts
@@ -481,6 +481,19 @@ describe('Test users', function () {
       expect(user.autoPlayVideo).to.be.false
     })
 
+    it('Should be able to change the autoPlayNextVideo attribute', async function () {
+      await updateMyUser({
+        url: server.url,
+        accessToken: accessTokenUser,
+        autoPlayNextVideo: true
+      })
+
+      const res = await getMyUserInformation(server.url, accessTokenUser)
+      const user = res.body
+
+      expect(user.autoPlayNextVideo).to.be.true
+    })
+
     it('Should be able to change the email attribute', async function () {
       await updateMyUser({
         url: server.url,
diff --git a/shared/models/users/user-update-me.model.ts b/shared/models/users/user-update-me.model.ts
index 99b9a65bd..0a833f84c 100644
--- a/shared/models/users/user-update-me.model.ts
+++ b/shared/models/users/user-update-me.model.ts
@@ -7,6 +7,7 @@ export interface UserUpdateMe {
 
   webTorrentEnabled?: boolean
   autoPlayVideo?: boolean
+  autoPlayNextVideo?: boolean
   videosHistoryEnabled?: boolean
   videoLanguages?: string[]
 
diff --git a/shared/models/users/user.model.ts b/shared/models/users/user.model.ts
index f67d262b0..1ca8ddcba 100644
--- a/shared/models/users/user.model.ts
+++ b/shared/models/users/user.model.ts
@@ -17,6 +17,7 @@ export interface User {
   adminFlags?: UserAdminFlag
 
   autoPlayVideo: boolean
+  autoPlayNextVideo: boolean
   webTorrentEnabled: boolean
   videosHistoryEnabled: boolean
   videoLanguages: string[]