diff --git a/docs/multimedia.md b/docs/multimedia.md
index 50cb939d5..f2d128e22 100644
--- a/docs/multimedia.md
+++ b/docs/multimedia.md
@@ -131,6 +131,116 @@ pageClass: routes
+## JavDB
+
+### 主页
+
+
+
+分类
+
+| 有碼 | 無碼 | 歐美 | FC2 |
+| -------- | ---------- | ------- | --- |
+| censored | uncensored | western | fc2 |
+
+排序
+
+| 发布日期排序 | 磁鏈更新排序 |
+| ------------ | ------------ |
+| 1 | 2 |
+
+过滤
+
+| 全部 | 可下载 | 含字幕 | 含短評 |
+| ---- | ------ | ------ | ------ |
+| 0 | 1 | 2 | 3 |
+
+
+
+### 分類
+
+
+
+::: tip 提示
+
+在 [分類](https://javdb.com/tags) 中选定分类后,URL 中 `tags?` 后的字段即为筛选参数。
+
+如 中 `c2=5&c10=1` 为筛选参数。
+
+:::
+
+分类
+
+| 有碼 | 無碼 | 歐美 | FC2 |
+| -------- | ---------- | ------- | --- |
+| censored | uncensored | western | fc2 |
+
+
+
+### 排行榜
+
+
+
+分类
+
+| 有碼 | 無碼 | 歐美 | FC2 |
+| -------- | ---------- | ------- | --- |
+| censored | uncensored | western | fc2 |
+
+时间
+
+| 日榜 | 週榜 | 月榜 |
+| ----- | ------ | ------- |
+| daily | weekly | monthly |
+
+
+
+### 搜索
+
+
+
+| 全部 | 可播放 | 單體作品 | 演員 | 片商 | 導演 | 系列 | 番號 | 可下載 | 字幕 | 預覽圖 |
+| ---- | -------- | -------- | ----- | ----- | -------- | ------ | ---- | -------- | ----- | ------- |
+| | playable | single | actor | maker | director | series | code | download | cnsub | preview |
+
+
+
+### 演員
+
+
+
+| 全部 | 可播放 | 單體作品 | 可下載 | 含字幕 |
+| ---- | ------ | -------- | ------ | ------ |
+| | p | s | d | c |
+
+所有演员编号参见 [演員庫](https://javdb.com/actors)
+
+
+
+### 系列
+
+
+
+| 全部 | 可播放 | 單體作品 | 可下載 | 字幕 | 預覽圖 |
+| ---- | -------- | -------- | -------- | ----- | ------- |
+| | playable | single | download | cnsub | preview |
+
+所有系列编号参见 [系列庫](https://javdb.com/series)
+
+
+
+### 片商
+
+
+
+| 全部 | 可播放 | 單體作品 | 可下載 | 字幕 | 預覽圖 |
+| ---- | -------- | -------- | -------- | ----- | ------- |
+| | playable | single | download | cnsub | preview |
+
+所有片商编号参见 [片商庫](https://javdb.com/makers)
+
+
+
## JavLibrary
### 影片
diff --git a/lib/router.js b/lib/router.js
index 8f0ec72ab..25c0cee9c 100644
--- a/lib/router.js
+++ b/lib/router.js
@@ -3241,6 +3241,15 @@ router.get('/appsales/:caty?/:time?', require('./routes/appsales/index'));
// CGTN
router.get('/cgtn/top', require('./routes/cgtn/top'));
+// JavDB
+router.get('/javdb/home/:caty?/:sort?/:filter?', require('./routes/javdb/home'));
+router.get('/javdb/search/:keyword?/:filter?', require('./routes/javdb/search'));
+router.get('/javdb/tags/:query?/:caty?', require('./routes/javdb/tags'));
+router.get('/javdb/actors/:id/:filter?', require('./routes/javdb/actors'));
+router.get('/javdb/makers/:id/:filter?', require('./routes/javdb/makers'));
+router.get('/javdb/series/:id/:filter?', require('./routes/javdb/series'));
+router.get('/javdb/rankings/:caty?/:time?', require('./routes/javdb/rankings'));
+
// World Economic Forum
router.get('/weforum/report/:lang?/:year?/:platform?', require('./routes/weforum/report'));
diff --git a/lib/routes/javdb/actors.js b/lib/routes/javdb/actors.js
new file mode 100644
index 000000000..0815709c5
--- /dev/null
+++ b/lib/routes/javdb/actors.js
@@ -0,0 +1,19 @@
+const utils = require('./utils');
+
+module.exports = async (ctx) => {
+ ctx.params.filter = ctx.params.filter || '';
+
+ const currentUrl = `${utils.rootUrl}/actors/${ctx.params.id}?t=${ctx.params.filter}`;
+
+ const filter = {
+ '': '',
+ p: '可播放',
+ s: '單體作品',
+ d: '可下載',
+ c: '含字幕',
+ };
+
+ const title = `JavDB${filter[ctx.params.filter] === '' ? '' : ` - ${filter[ctx.params.filter]}`} `;
+
+ ctx.state.data = await utils.ProcessItems(ctx, currentUrl, title);
+};
diff --git a/lib/routes/javdb/home.js b/lib/routes/javdb/home.js
new file mode 100644
index 000000000..8d49953c3
--- /dev/null
+++ b/lib/routes/javdb/home.js
@@ -0,0 +1,32 @@
+const utils = require('./utils');
+
+module.exports = async (ctx) => {
+ ctx.params.caty = ctx.params.caty || 'censored';
+ ctx.params.sort = ctx.params.sort || '2';
+ ctx.params.filter = ctx.params.filter || '1';
+
+ const currentUrl = `${utils.rootUrl}/${ctx.params.caty === 'censored' ? '' : ctx.params.caty}?vft=${ctx.params.filter}&vst=${ctx.params.sort}`;
+
+ const category = {
+ censored: '有碼',
+ uncensored: '無碼',
+ western: '歐美',
+ fc2: 'FC2',
+ };
+
+ const filter = {
+ 0: '',
+ 1: '可下载',
+ 2: '含字幕',
+ 3: '含短評',
+ };
+
+ const sort = {
+ 1: '发布日期排序',
+ 2: '磁鏈更新排序',
+ };
+
+ const title = `${category[ctx.params.caty]} - JavDB - ${filter[ctx.params.filter] === '' ? '|' : `${filter[ctx.params.filter]} | `}${sort[ctx.params.sort]}`;
+
+ ctx.state.data = await utils.ProcessItems(ctx, currentUrl, title);
+};
diff --git a/lib/routes/javdb/makers.js b/lib/routes/javdb/makers.js
new file mode 100644
index 000000000..c6b06f95f
--- /dev/null
+++ b/lib/routes/javdb/makers.js
@@ -0,0 +1,20 @@
+const utils = require('./utils');
+
+module.exports = async (ctx) => {
+ ctx.params.filter = ctx.params.filter || '';
+
+ const currentUrl = `${utils.rootUrl}/makers/${ctx.params.id}?f=${ctx.params.filter}`;
+
+ const filter = {
+ '': '',
+ playable: '可播放',
+ single: '單體作品',
+ download: '可下載',
+ cnsub: '字幕',
+ preview: '預覽圖',
+ };
+
+ const title = `JavDB${filter[ctx.params.filter] === '' ? '' : ` - ${filter[ctx.params.filter]}`} `;
+
+ ctx.state.data = await utils.ProcessItems(ctx, currentUrl, title);
+};
diff --git a/lib/routes/javdb/rankings.js b/lib/routes/javdb/rankings.js
new file mode 100644
index 000000000..ee429abc2
--- /dev/null
+++ b/lib/routes/javdb/rankings.js
@@ -0,0 +1,12 @@
+const utils = require('./utils');
+
+module.exports = async (ctx) => {
+ ctx.params.caty = ctx.params.caty || 'censored';
+ ctx.params.time = ctx.params.time || 'daily';
+
+ const currentUrl = `${utils.rootUrl}/rankings/video_${ctx.params.caty}?period=${ctx.params.time}`;
+
+ const title = 'JavDB';
+
+ ctx.state.data = await utils.ProcessItems(ctx, currentUrl, title);
+};
diff --git a/lib/routes/javdb/search.js b/lib/routes/javdb/search.js
new file mode 100644
index 000000000..bdf0bc5ef
--- /dev/null
+++ b/lib/routes/javdb/search.js
@@ -0,0 +1,26 @@
+const utils = require('./utils');
+
+module.exports = async (ctx) => {
+ ctx.params.filter = ctx.params.filter || '';
+ ctx.params.keyword = ctx.params.keyword || '';
+
+ const currentUrl = `${utils.rootUrl}/search?q=${ctx.params.keyword}&f=${ctx.params.filter}`;
+
+ const filter = {
+ '': '',
+ playable: '可播放',
+ single: '單體作品',
+ actor: '演員',
+ maker: '片商',
+ director: '導演',
+ series: '系列',
+ code: '番號',
+ download: '可下載',
+ cnsub: '字幕',
+ preview: '預覽圖',
+ };
+
+ const title = `關鍵字 ${ctx.params.keyword} ${filter[ctx.params.filter] === '' ? '' : `+ ${filter[ctx.params.filter]}`} 搜索結果 - JavDB `;
+
+ ctx.state.data = await utils.ProcessItems(ctx, currentUrl, title);
+};
diff --git a/lib/routes/javdb/series.js b/lib/routes/javdb/series.js
new file mode 100644
index 000000000..9189c21be
--- /dev/null
+++ b/lib/routes/javdb/series.js
@@ -0,0 +1,20 @@
+const utils = require('./utils');
+
+module.exports = async (ctx) => {
+ ctx.params.filter = ctx.params.filter || '';
+
+ const currentUrl = `${utils.rootUrl}/series/${ctx.params.id}?f=${ctx.params.filter}`;
+
+ const filter = {
+ '': '',
+ playable: '可播放',
+ single: '單體作品',
+ download: '可下載',
+ cnsub: '字幕',
+ preview: '預覽圖',
+ };
+
+ const title = `JavDB${filter[ctx.params.filter] === '' ? '' : ` - ${filter[ctx.params.filter]}`} `;
+
+ ctx.state.data = await utils.ProcessItems(ctx, currentUrl, title);
+};
diff --git a/lib/routes/javdb/tags.js b/lib/routes/javdb/tags.js
new file mode 100644
index 000000000..efec484cb
--- /dev/null
+++ b/lib/routes/javdb/tags.js
@@ -0,0 +1,12 @@
+const utils = require('./utils');
+
+module.exports = async (ctx) => {
+ ctx.params.caty = ctx.params.caty || 'censored';
+ ctx.params.query = ctx.params.query || '';
+
+ const currentUrl = `${utils.rootUrl}/tags${ctx.params.caty === 'censored' ? '' : `/${ctx.params.caty}`}?${ctx.params.query}`;
+
+ const title = `JavDB${ctx.params.query === '' ? '' : ` - ${ctx.params.query}`} `;
+
+ ctx.state.data = await utils.ProcessItems(ctx, currentUrl, title);
+};
diff --git a/lib/routes/javdb/utils.js b/lib/routes/javdb/utils.js
new file mode 100644
index 000000000..78e5ad8ee
--- /dev/null
+++ b/lib/routes/javdb/utils.js
@@ -0,0 +1,72 @@
+const got = require('@/utils/got');
+const cheerio = require('cheerio');
+
+const rootUrl = 'https://javdb.com';
+
+module.exports = {
+ rootUrl: rootUrl,
+ ProcessItems: async (ctx, currentUrl, title) => {
+ const response = await got({
+ method: 'get',
+ url: currentUrl,
+ });
+
+ const $ = cheerio.load(response.data);
+
+ $('.tags').remove();
+
+ const list = $('.grid-item a')
+ .slice(0, 5)
+ .map((_, item) => {
+ item = $(item);
+ return {
+ title: item.text(),
+ link: `${rootUrl}${item.attr('href')}`,
+ pubDate: new Date(item.find('.meta').text()).toUTCString(),
+ };
+ })
+ .get();
+
+ const items = await Promise.all(
+ list.map(
+ async (item) =>
+ await ctx.cache.tryGet(item.link, async () => {
+ const detailResponse = await got({
+ method: 'get',
+ url: item.link,
+ });
+ const content = cheerio.load(detailResponse.data);
+
+ item.enclosure_url = content('#magnets-content button[data-clipboard-text]').eq(0).attr('data-clipboard-text');
+ item.enclosure_type = 'application/x-bittorrent';
+
+ content('icon, .review-buttons, .copy-to-clipboard').remove();
+ content('#modal-review-watched, #modal-save-list').remove();
+ content('.video-cover').eq(1).remove();
+
+ content('img.video-cover').attr('src', content(this).parent().attr('href'));
+
+ content('.preview-images img').each(function () {
+ content(this).removeAttr('data-src');
+ content(this).attr('src', content(this).parent().attr('href'));
+ });
+
+ content('#preview-video').css('display', 'block');
+
+ item.description = content('.movie-info-panel .columns').html() + content('#magnets-content').html() + content('.preview-images').html();
+
+ return item;
+ })
+ )
+ );
+
+ const htmlTitle = $('title').text();
+ const subject = htmlTitle.indexOf('|') === -1 ? '' : htmlTitle.split('|')[0];
+
+ return {
+ title: subject === '' ? title : `${subject} - ${title}`,
+ link: currentUrl,
+ item: items,
+ };
+ },
+};