diff --git a/client/src/app/+admin/moderation/video-block-list/video-block-list.component.ts b/client/src/app/+admin/moderation/video-block-list/video-block-list.component.ts
index 3edcb1c63..7baf34ca2 100644
--- a/client/src/app/+admin/moderation/video-block-list/video-block-list.component.ts
+++ b/client/src/app/+admin/moderation/video-block-list/video-block-list.component.ts
@@ -28,12 +28,17 @@ export class VideoBlockListComponent extends RestTable implements OnInit {
 
   inputFilters: AdvancedInputFilter[] = [
     {
-      queryParams: { search: 'type:auto' },
-      label: $localize`Automatic blocks`
-    },
-    {
-      queryParams: { search: 'type:manual' },
-      label: $localize`Manual blocks`
+      title: $localize`Advanced filters`,
+      children: [
+        {
+          queryParams: { search: 'type:auto' },
+          label: $localize`Automatic blocks`
+        },
+        {
+          queryParams: { search: 'type:manual' },
+          label: $localize`Manual blocks`
+        }
+      ]
     }
   ]
 
diff --git a/client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.ts b/client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.ts
index c09ce7293..a60b228af 100644
--- a/client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.ts
+++ b/client/src/app/+admin/moderation/video-comment-list/video-comment-list.component.ts
@@ -44,12 +44,17 @@ export class VideoCommentListComponent extends RestTable implements OnInit {
 
   inputFilters: AdvancedInputFilter[] = [
     {
-      queryParams: { search: 'local:true' },
-      label: $localize`Local comments`
-    },
-    {
-      queryParams: { search: 'local:false' },
-      label: $localize`Remote comments`
+      title: $localize`Advanced filters`,
+      children: [
+        {
+          queryParams: { search: 'local:true' },
+          label: $localize`Local comments`
+        },
+        {
+          queryParams: { search: 'local:false' },
+          label: $localize`Remote comments`
+        }
+      ]
     }
   ]
 
diff --git a/client/src/app/+admin/users/user-list/user-list.component.ts b/client/src/app/+admin/users/user-list/user-list.component.ts
index 1030759df..548e6e80f 100644
--- a/client/src/app/+admin/users/user-list/user-list.component.ts
+++ b/client/src/app/+admin/users/user-list/user-list.component.ts
@@ -36,8 +36,13 @@ export class UserListComponent extends RestTable implements OnInit {
 
   inputFilters: AdvancedInputFilter[] = [
     {
-      queryParams: { search: 'banned:true' },
-      label: $localize`Banned users`
+      title: $localize`Advanced filters`,
+      children: [
+        {
+          queryParams: { search: 'banned:true' },
+          label: $localize`Banned users`
+        }
+      ]
     }
   ]
 
diff --git a/client/src/app/+my-library/my-follows/my-followers.component.ts b/client/src/app/+my-library/my-follows/my-followers.component.ts
index 413d524df..4a72b983f 100644
--- a/client/src/app/+my-library/my-follows/my-followers.component.ts
+++ b/client/src/app/+my-library/my-follows/my-followers.component.ts
@@ -37,12 +37,19 @@ export class MyFollowersComponent implements OnInit {
     }
 
     this.auth.userInformationLoaded.subscribe(() => {
-      this.inputFilters = this.auth.getUser().videoChannels.map(c => {
+      const channelFilters = this.auth.getUser().videoChannels.map(c => {
         return {
           queryParams: { search: 'channel:' + c.name },
-          label: $localize`Followers of ${c.name}`
+          label: c.name
         }
       })
+
+      this.inputFilters = [
+        {
+          title: $localize`Channel filters`,
+          children: channelFilters
+        }
+      ]
     })
   }
 
diff --git a/client/src/app/+my-library/my-videos/my-videos.component.ts b/client/src/app/+my-library/my-videos/my-videos.component.ts
index b1f3baf80..a117d0915 100644
--- a/client/src/app/+my-library/my-videos/my-videos.component.ts
+++ b/client/src/app/+my-library/my-videos/my-videos.component.ts
@@ -9,7 +9,7 @@ import { AdvancedInputFilter } from '@app/shared/shared-forms'
 import { DropdownAction, Video, VideoService } from '@app/shared/shared-main'
 import { LiveStreamInformationComponent } from '@app/shared/shared-video-live'
 import { MiniatureDisplayOptions, SelectionType, VideosSelectionComponent } from '@app/shared/shared-video-miniature'
-import { VideoSortField } from '@shared/models'
+import { VideoChannel, VideoSortField } from '@shared/models'
 import { VideoChangeOwnershipComponent } from './modals/video-change-ownership.component'
 
 @Component({
@@ -47,16 +47,12 @@ export class MyVideosComponent implements OnInit, DisableForReuseHook {
 
   user: User
 
-  inputFilters: AdvancedInputFilter[] = [
-    {
-      queryParams: { search: 'isLive:true' },
-      label: $localize`Only live videos`
-    }
-  ]
+  inputFilters: AdvancedInputFilter[]
 
   disabled = false
 
   private search: string
+  private userChannels: VideoChannel[] = []
 
   constructor (
     protected router: Router,
@@ -79,6 +75,35 @@ export class MyVideosComponent implements OnInit, DisableForReuseHook {
     if (this.route.snapshot.queryParams['search']) {
       this.search = this.route.snapshot.queryParams['search']
     }
+
+    this.authService.userInformationLoaded.subscribe(() => {
+      this.user = this.authService.getUser()
+      this.userChannels = this.user.videoChannels
+
+      const channelFilters = this.userChannels.map(c => {
+        return {
+          queryParams: { search: 'channel:' + c.name },
+          label: c.name
+        }
+      })
+
+      this.inputFilters = [
+        {
+          title: $localize`Advanced filters`,
+          children: [
+            {
+              queryParams: { search: 'isLive:true' },
+              label: $localize`Only live videos`
+            }
+          ]
+        },
+
+        {
+          title: $localize`Channel filters`,
+          children: channelFilters
+        }
+      ]
+    })
   }
 
   onSearch (search: string) {
@@ -105,7 +130,12 @@ export class MyVideosComponent implements OnInit, DisableForReuseHook {
   getVideosObservable (page: number) {
     const newPagination = immutableAssign(this.pagination, { currentPage: page })
 
-    return this.videoService.getMyVideos(newPagination, this.sort, this.search)
+    return this.videoService.getMyVideos({
+      videoPagination: newPagination,
+      sort: this.sort,
+      userChannels: this.userChannels,
+      search: this.search
+    })
       .pipe(
         tap(res => this.pagination.totalItems = res.total)
       )
diff --git a/client/src/app/shared/shared-abuse-list/abuse-list-table.component.ts b/client/src/app/shared/shared-abuse-list/abuse-list-table.component.ts
index 33e9fd8de..297993e39 100644
--- a/client/src/app/shared/shared-abuse-list/abuse-list-table.component.ts
+++ b/client/src/app/shared/shared-abuse-list/abuse-list-table.component.ts
@@ -39,24 +39,29 @@ export class AbuseListTableComponent extends RestTable implements OnInit {
 
   inputFilters: AdvancedInputFilter[] = [
     {
-      queryParams: { search: 'state:pending' },
-      label: $localize`Unsolved reports`
-    },
-    {
-      queryParams: { search: 'state:accepted' },
-      label: $localize`Accepted reports`
-    },
-    {
-      queryParams: { search: 'state:rejected' },
-      label: $localize`Refused reports`
-    },
-    {
-      queryParams: { search: 'videoIs:blacklisted' },
-      label: $localize`Reports with blocked videos`
-    },
-    {
-      queryParams: { search: 'videoIs:deleted' },
-      label: $localize`Reports with deleted videos`
+      title: $localize`Advanced filters`,
+      children: [
+        {
+          queryParams: { search: 'state:pending' },
+          label: $localize`Unsolved reports`
+        },
+        {
+          queryParams: { search: 'state:accepted' },
+          label: $localize`Accepted reports`
+        },
+        {
+          queryParams: { search: 'state:rejected' },
+          label: $localize`Refused reports`
+        },
+        {
+          queryParams: { search: 'videoIs:blacklisted' },
+          label: $localize`Reports with blocked videos`
+        },
+        {
+          queryParams: { search: 'videoIs:deleted' },
+          label: $localize`Reports with deleted videos`
+        }
+      ]
     }
   ]
 
diff --git a/client/src/app/shared/shared-forms/advanced-input-filter.component.html b/client/src/app/shared/shared-forms/advanced-input-filter.component.html
index 10d1296cf..c662b9bb6 100644
--- a/client/src/app/shared/shared-forms/advanced-input-filter.component.html
+++ b/client/src/app/shared/shared-forms/advanced-input-filter.component.html
@@ -5,11 +5,13 @@
     </div>
 
     <div role="menu" ngbDropdownMenu>
-      <h6 class="dropdown-header" i18n>Advanced filters</h6>
+      <ng-container *ngFor="let group of filters">
+        <h6 class="dropdown-header">{{ group.title }}</h6>
 
-      <a *ngFor="let filter of filters" [routerLink]="[ '.' ]" [queryParams]="filter.queryParams" class="dropdown-item">
-        {{ filter.label }}
-      </a>
+        <a *ngFor="let filter of group.children" [routerLink]="[ '.' ]" [queryParams]="filter.queryParams" class="dropdown-item">
+          {{ filter.label }}
+        </a>
+      </ng-container>
     </div>
   </div>
 
diff --git a/client/src/app/shared/shared-forms/advanced-input-filter.component.ts b/client/src/app/shared/shared-forms/advanced-input-filter.component.ts
index 8315662b4..a12dddf7a 100644
--- a/client/src/app/shared/shared-forms/advanced-input-filter.component.ts
+++ b/client/src/app/shared/shared-forms/advanced-input-filter.component.ts
@@ -5,8 +5,12 @@ import { AfterViewInit, Component, EventEmitter, Input, OnInit, Output } from '@
 import { ActivatedRoute, Params, Router } from '@angular/router'
 
 export type AdvancedInputFilter = {
-  label: string
-  queryParams: Params
+  title: string
+
+  children: {
+    label: string
+    queryParams: Params
+  }[]
 }
 
 const logger = debug('peertube:AdvancedInputFilterComponent')
diff --git a/client/src/app/shared/shared-main/video/video.service.ts b/client/src/app/shared/shared-main/video/video.service.ts
index 2f43f1b9d..7935569e7 100644
--- a/client/src/app/shared/shared-main/video/video.service.ts
+++ b/client/src/app/shared/shared-main/video/video.service.ts
@@ -13,6 +13,7 @@ import {
   UserVideoRateType,
   UserVideoRateUpdate,
   Video as VideoServerModel,
+  VideoChannel as VideoChannelServerModel,
   VideoConstant,
   VideoDetails as VideoDetailsServerModel,
   VideoFileMetadata,
@@ -122,7 +123,14 @@ export class VideoService {
                .pipe(catchError(err => this.restExtractor.handleError(err)))
   }
 
-  getMyVideos (videoPagination: ComponentPaginationLight, sort: VideoSortField, search?: string): Observable<ResultList<Video>> {
+  getMyVideos (options: {
+    videoPagination: ComponentPaginationLight
+    sort: VideoSortField
+    userChannels?: VideoChannelServerModel[]
+    search?: string
+  }): Observable<ResultList<Video>> {
+    const { videoPagination, sort, userChannels = [], search } = options
+
     const pagination = this.restService.componentToRestPagination(videoPagination)
 
     let params = new HttpParams()
@@ -133,6 +141,16 @@ export class VideoService {
         isLive: {
           prefix: 'isLive:',
           isBoolean: true
+        },
+        channelId: {
+          prefix: 'channel:',
+          handler: (name: string) => {
+            const channel = userChannels.find(c => c.name === name)
+
+            if (channel) return channel.id
+
+            return undefined
+          }
         }
       })
 
diff --git a/server/controllers/api/users/me.ts b/server/controllers/api/users/me.ts
index 83b774d3c..6bacdbbb6 100644
--- a/server/controllers/api/users/me.ts
+++ b/server/controllers/api/users/me.ts
@@ -25,7 +25,7 @@ import {
   usersUpdateMeValidator,
   usersVideoRatingValidator
 } from '../../../middlewares'
-import { deleteMeValidator, videoImportsSortValidator, videosSortValidator } from '../../../middlewares/validators'
+import { deleteMeValidator, usersVideosValidator, videoImportsSortValidator, videosSortValidator } from '../../../middlewares/validators'
 import { updateAvatarValidator } from '../../../middlewares/validators/actor-image'
 import { AccountModel } from '../../../models/account/account'
 import { AccountVideoRateModel } from '../../../models/account/account-video-rate'
@@ -69,6 +69,7 @@ meRouter.get('/me/videos',
   videosSortValidator,
   setDefaultVideosSort,
   setDefaultPagination,
+  asyncMiddleware(usersVideosValidator),
   asyncMiddleware(getUserVideos)
 )
 
@@ -113,6 +114,7 @@ async function getUserVideos (req: express.Request, res: express.Response) {
     count: req.query.count,
     sort: req.query.sort,
     search: req.query.search,
+    channelId: res.locals.videoChannel?.id,
     isLive: req.query.isLive
   }, 'filter:api.user.me.videos.list.params')
 
diff --git a/server/middlewares/validators/users.ts b/server/middlewares/validators/users.ts
index c6eeeaf18..8f1a7801f 100644
--- a/server/middlewares/validators/users.ts
+++ b/server/middlewares/validators/users.ts
@@ -4,7 +4,7 @@ import { omit } from 'lodash'
 import { Hooks } from '@server/lib/plugins/hooks'
 import { MUserDefault } from '@server/types/models'
 import { HttpStatusCode, UserRegister, UserRole } from '@shared/models'
-import { toBooleanOrNull, toIntOrNull } from '../../helpers/custom-validators/misc'
+import { isBooleanValid, isIdValid, toBooleanOrNull, toIntOrNull } from '../../helpers/custom-validators/misc'
 import { isThemeNameValid } from '../../helpers/custom-validators/plugins'
 import {
   isUserAdminFlagsValid,
@@ -31,7 +31,7 @@ import { Redis } from '../../lib/redis'
 import { isSignupAllowed, isSignupAllowedForCurrentIP } from '../../lib/signup'
 import { ActorModel } from '../../models/actor/actor'
 import { UserModel } from '../../models/user/user'
-import { areValidationErrors, doesVideoExist, isValidVideoIdParam } from './shared'
+import { areValidationErrors, doesVideoChannelIdExist, doesVideoExist, isValidVideoIdParam } from './shared'
 
 const usersListValidator = [
   query('blocked')
@@ -318,6 +318,28 @@ const usersVideoRatingValidator = [
   }
 ]
 
+const usersVideosValidator = [
+  query('isLive')
+    .optional()
+    .customSanitizer(toBooleanOrNull)
+    .custom(isBooleanValid).withMessage('Should have a valid live boolean'),
+
+  query('channelId')
+    .optional()
+    .customSanitizer(toIntOrNull)
+    .custom(isIdValid).withMessage('Should have a valid channel id'),
+
+  async (req: express.Request, res: express.Response, next: express.NextFunction) => {
+    logger.debug('Checking usersVideosValidator parameters', { parameters: req.params })
+
+    if (areValidationErrors(req, res)) return
+
+    if (req.query.channelId && !await doesVideoChannelIdExist(req.query.channelId, res)) return
+
+    return next()
+  }
+]
+
 const ensureUserRegistrationAllowed = [
   async (req: express.Request, res: express.Response, next: express.NextFunction) => {
     const allowedParams = {
@@ -513,6 +535,7 @@ export {
   ensureUserRegistrationAllowed,
   ensureUserRegistrationAllowedForIP,
   usersGetValidator,
+  usersVideosValidator,
   usersAskResetPasswordValidator,
   usersResetPasswordValidator,
   usersAskSendVerifyEmailValidator,
diff --git a/server/models/video/video.ts b/server/models/video/video.ts
index d2daf18ee..4044287ee 100644
--- a/server/models/video/video.ts
+++ b/server/models/video/video.ts
@@ -978,10 +978,12 @@ export class VideoModel extends Model<Partial<AttributesOnly<VideoModel>>> {
     start: number
     count: number
     sort: string
+
+    channelId?: number
     isLive?: boolean
     search?: string
   }) {
-    const { accountId, start, count, sort, search, isLive } = options
+    const { accountId, channelId, start, count, sort, search, isLive } = options
 
     function buildBaseQuery (): FindOptions {
       const where: WhereOptions = {}
@@ -996,6 +998,10 @@ export class VideoModel extends Model<Partial<AttributesOnly<VideoModel>>> {
         where.isLive = isLive
       }
 
+      const channelWhere = channelId
+        ? { id: channelId }
+        : {}
+
       const baseQuery = {
         offset: start,
         limit: count,
@@ -1005,6 +1011,7 @@ export class VideoModel extends Model<Partial<AttributesOnly<VideoModel>>> {
           {
             model: VideoChannelModel,
             required: true,
+            where: channelWhere,
             include: [
               {
                 model: AccountModel,
diff --git a/server/tests/api/check-params/videos.ts b/server/tests/api/check-params/videos.ts
index e11ca0c82..d02b6e156 100644
--- a/server/tests/api/check-params/videos.ts
+++ b/server/tests/api/check-params/videos.ts
@@ -119,6 +119,20 @@ describe('Test videos API validator', function () {
       await checkBadSortPagination(server.url, path, server.accessToken)
     })
 
+    it('Should fail with an invalid channel', async function () {
+      await makeGetRequest({ url: server.url, token: server.accessToken, path, query: { channelId: 'toto' } })
+    })
+
+    it('Should fail with an unknown channel', async function () {
+      await makeGetRequest({
+        url: server.url,
+        token: server.accessToken,
+        path,
+        query: { channelId: 89898 },
+        expectedStatus: HttpStatusCode.NOT_FOUND_404
+      })
+    })
+
     it('Should success with the correct parameters', async function () {
       await makeGetRequest({ url: server.url, token: server.accessToken, path, expectedStatus: HttpStatusCode.OK_200 })
     })
diff --git a/server/tests/api/users/users.ts b/server/tests/api/users/users.ts
index 085d9d870..6c41e7d56 100644
--- a/server/tests/api/users/users.ts
+++ b/server/tests/api/users/users.ts
@@ -318,6 +318,8 @@ describe('Test users', function () {
         fixture: 'video_short.webm'
       }
       await server.videos.upload({ token: userToken, attributes })
+
+      await server.channels.create({ token: userToken, attributes: { name: 'other_channel' } })
     })
 
     it('Should have video quota updated', async function () {
@@ -340,6 +342,29 @@ describe('Test users', function () {
       expect(video.previewPath).to.not.be.null
     })
 
+    it('Should be able to filter by channel in my videos', async function () {
+      const myInfo = await server.users.getMyInfo({ token: userToken })
+      const mainChannel = myInfo.videoChannels.find(c => c.name !== 'other_channel')
+      const otherChannel = myInfo.videoChannels.find(c => c.name === 'other_channel')
+
+      {
+        const { total, data } = await server.videos.listMyVideos({ token: userToken, channelId: mainChannel.id })
+        expect(total).to.equal(1)
+        expect(data).to.have.lengthOf(1)
+
+        const video: Video = data[0]
+        expect(video.name).to.equal('super user video')
+        expect(video.thumbnailPath).to.not.be.null
+        expect(video.previewPath).to.not.be.null
+      }
+
+      {
+        const { total, data } = await server.videos.listMyVideos({ token: userToken, channelId: otherChannel.id })
+        expect(total).to.equal(0)
+        expect(data).to.have.lengthOf(0)
+      }
+    })
+
     it('Should be able to search in my videos', async function () {
       {
         const { total, data } = await server.videos.listMyVideos({ token: userToken, sort: '-createdAt', search: 'user video' })
diff --git a/shared/extra-utils/videos/videos-command.ts b/shared/extra-utils/videos/videos-command.ts
index 99f56a34c..c1a9ec806 100644
--- a/shared/extra-utils/videos/videos-command.ts
+++ b/shared/extra-utils/videos/videos-command.ts
@@ -207,6 +207,7 @@ export class VideosCommand extends AbstractCommand {
     sort?: string
     search?: string
     isLive?: boolean
+    channelId?: number
   } = {}) {
     const path = '/api/v1/users/me/videos'
 
@@ -214,7 +215,7 @@ export class VideosCommand extends AbstractCommand {
       ...options,
 
       path,
-      query: pick(options, [ 'start', 'count', 'sort', 'search', 'isLive' ]),
+      query: pick(options, [ 'start', 'count', 'sort', 'search', 'isLive', 'channelId' ]),
       implicitToken: true,
       defaultExpectedStatus: HttpStatusCode.OK_200
     })