douyin-downloader 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +114 -0
- package/dist/bin/dydl.d.ts +2 -0
- package/dist/bin/dydl.js +17 -0
- package/dist/bin/dydl.js.map +1 -0
- package/dist/src/cli/commands/check.d.ts +10 -0
- package/dist/src/cli/commands/check.js +102 -0
- package/dist/src/cli/commands/check.js.map +1 -0
- package/dist/src/cli/commands/info.d.ts +10 -0
- package/dist/src/cli/commands/info.js +106 -0
- package/dist/src/cli/commands/info.js.map +1 -0
- package/dist/src/cli/commands/list.d.ts +10 -0
- package/dist/src/cli/commands/list.js +85 -0
- package/dist/src/cli/commands/list.js.map +1 -0
- package/dist/src/cli/commands/login.d.ts +10 -0
- package/dist/src/cli/commands/login.js +158 -0
- package/dist/src/cli/commands/login.js.map +1 -0
- package/dist/src/cli/commands/open.d.ts +10 -0
- package/dist/src/cli/commands/open.js +141 -0
- package/dist/src/cli/commands/open.js.map +1 -0
- package/dist/src/cli/commands/video.d.ts +10 -0
- package/dist/src/cli/commands/video.js +209 -0
- package/dist/src/cli/commands/video.js.map +1 -0
- package/dist/src/cli/index.d.ts +15 -0
- package/dist/src/cli/index.js +134 -0
- package/dist/src/cli/index.js.map +1 -0
- package/dist/src/cli/progress-display.d.ts +80 -0
- package/dist/src/cli/progress-display.js +225 -0
- package/dist/src/cli/progress-display.js.map +1 -0
- package/dist/src/cli/utils.d.ts +31 -0
- package/dist/src/cli/utils.js +171 -0
- package/dist/src/cli/utils.js.map +1 -0
- package/dist/src/douyin/auth/cookie-path.d.ts +22 -0
- package/dist/src/douyin/auth/cookie-path.js +72 -0
- package/dist/src/douyin/auth/cookie-path.js.map +1 -0
- package/dist/src/douyin/auth/cookie-storage.d.ts +19 -0
- package/dist/src/douyin/auth/cookie-storage.js +65 -0
- package/dist/src/douyin/auth/cookie-storage.js.map +1 -0
- package/dist/src/douyin/auth/errors.d.ts +28 -0
- package/dist/src/douyin/auth/errors.js +49 -0
- package/dist/src/douyin/auth/errors.js.map +1 -0
- package/dist/src/douyin/auth/getDefaultCookiePath.d.ts +24 -0
- package/dist/src/douyin/auth/getDefaultCookiePath.js +90 -0
- package/dist/src/douyin/auth/getDefaultCookiePath.js.map +1 -0
- package/dist/src/douyin/auth/index.d.ts +16 -0
- package/dist/src/douyin/auth/index.js +68 -0
- package/dist/src/douyin/auth/index.js.map +1 -0
- package/dist/src/douyin/auth/isValidCookie.d.ts +18 -0
- package/dist/src/douyin/auth/isValidCookie.js +60 -0
- package/dist/src/douyin/auth/isValidCookie.js.map +1 -0
- package/dist/src/douyin/auth/loadAndValidateCookie.d.ts +17 -0
- package/dist/src/douyin/auth/loadAndValidateCookie.js +45 -0
- package/dist/src/douyin/auth/loadAndValidateCookie.js.map +1 -0
- package/dist/src/douyin/auth/loadCookie.d.ts +17 -0
- package/dist/src/douyin/auth/loadCookie.js +79 -0
- package/dist/src/douyin/auth/loadCookie.js.map +1 -0
- package/dist/src/douyin/auth/login.d.ts +33 -0
- package/dist/src/douyin/auth/login.js +157 -0
- package/dist/src/douyin/auth/login.js.map +1 -0
- package/dist/src/douyin/auth/saveCookie.d.ts +17 -0
- package/dist/src/douyin/auth/saveCookie.js +89 -0
- package/dist/src/douyin/auth/saveCookie.js.map +1 -0
- package/dist/src/douyin/auth/validate.d.ts +11 -0
- package/dist/src/douyin/auth/validate.js +104 -0
- package/dist/src/douyin/auth/validate.js.map +1 -0
- package/dist/src/douyin/browser/manager.d.ts +54 -0
- package/dist/src/douyin/browser/manager.js +344 -0
- package/dist/src/douyin/browser/manager.js.map +1 -0
- package/dist/src/douyin/download/download-manager.d.ts +25 -0
- package/dist/src/douyin/download/download-manager.js +107 -0
- package/dist/src/douyin/download/download-manager.js.map +1 -0
- package/dist/src/douyin/download/error-handler.d.ts +49 -0
- package/dist/src/douyin/download/error-handler.js +160 -0
- package/dist/src/douyin/download/error-handler.js.map +1 -0
- package/dist/src/douyin/download/index.d.ts +39 -0
- package/dist/src/douyin/download/index.js +156 -0
- package/dist/src/douyin/download/index.js.map +1 -0
- package/dist/src/douyin/download/path-formatter.d.ts +42 -0
- package/dist/src/douyin/download/path-formatter.js +107 -0
- package/dist/src/douyin/download/path-formatter.js.map +1 -0
- package/dist/src/douyin/download/video-downloader.d.ts +35 -0
- package/dist/src/douyin/download/video-downloader.js +223 -0
- package/dist/src/douyin/download/video-downloader.js.map +1 -0
- package/dist/src/douyin/index.d.ts +19 -0
- package/dist/src/douyin/index.js +52 -0
- package/dist/src/douyin/index.js.map +1 -0
- package/dist/src/douyin/info/batch-processor.d.ts +15 -0
- package/dist/src/douyin/info/batch-processor.js +65 -0
- package/dist/src/douyin/info/batch-processor.js.map +1 -0
- package/dist/src/douyin/info/browser-manager.d.ts +56 -0
- package/dist/src/douyin/info/browser-manager.js +225 -0
- package/dist/src/douyin/info/browser-manager.js.map +1 -0
- package/dist/src/douyin/info/error-handler.d.ts +36 -0
- package/dist/src/douyin/info/error-handler.js +172 -0
- package/dist/src/douyin/info/error-handler.js.map +1 -0
- package/dist/src/douyin/info/fetch-video-detail.d.ts +14 -0
- package/dist/src/douyin/info/fetch-video-detail.js +247 -0
- package/dist/src/douyin/info/fetch-video-detail.js.map +1 -0
- package/dist/src/douyin/info/index.d.ts +29 -0
- package/dist/src/douyin/info/index.js +85 -0
- package/dist/src/douyin/info/index.js.map +1 -0
- package/dist/src/douyin/info/text-processor.d.ts +15 -0
- package/dist/src/douyin/info/text-processor.js +47 -0
- package/dist/src/douyin/info/text-processor.js.map +1 -0
- package/dist/src/douyin/info/user.d.ts +26 -0
- package/dist/src/douyin/info/user.js +237 -0
- package/dist/src/douyin/info/user.js.map +1 -0
- package/dist/src/douyin/parser/containsDouyinLink.d.ts +18 -0
- package/dist/src/douyin/parser/containsDouyinLink.js +27 -0
- package/dist/src/douyin/parser/containsDouyinLink.js.map +1 -0
- package/dist/src/douyin/parser/extract-links.d.ts +23 -0
- package/dist/src/douyin/parser/extract-links.js +79 -0
- package/dist/src/douyin/parser/extract-links.js.map +1 -0
- package/dist/src/douyin/parser/extractDouyinLinks.d.ts +18 -0
- package/dist/src/douyin/parser/extractDouyinLinks.js +58 -0
- package/dist/src/douyin/parser/extractDouyinLinks.js.map +1 -0
- package/dist/src/douyin/parser/index.d.ts +35 -0
- package/dist/src/douyin/parser/index.js +70 -0
- package/dist/src/douyin/parser/index.js.map +1 -0
- package/dist/src/douyin/parser/link-patterns.d.ts +34 -0
- package/dist/src/douyin/parser/link-patterns.js +121 -0
- package/dist/src/douyin/parser/link-patterns.js.map +1 -0
- package/dist/src/douyin/parser/parse-batch.d.ts +26 -0
- package/dist/src/douyin/parser/parse-batch.js +67 -0
- package/dist/src/douyin/parser/parse-batch.js.map +1 -0
- package/dist/src/douyin/parser/parseDouyinLinks.d.ts +30 -0
- package/dist/src/douyin/parser/parseDouyinLinks.js +164 -0
- package/dist/src/douyin/parser/parseDouyinLinks.js.map +1 -0
- package/dist/src/douyin/parser/resolve-links.d.ts +25 -0
- package/dist/src/douyin/parser/resolve-links.js +131 -0
- package/dist/src/douyin/parser/resolve-links.js.map +1 -0
- package/dist/src/index.d.ts +16 -0
- package/dist/src/index.js +72 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/types.d.ts +217 -0
- package/dist/src/types.js +6 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/utils/browser.d.ts +73 -0
- package/dist/src/utils/browser.js +96 -0
- package/dist/src/utils/browser.js.map +1 -0
- package/dist/src/utils/error.d.ts +160 -0
- package/dist/src/utils/error.js +334 -0
- package/dist/src/utils/error.js.map +1 -0
- package/dist/src/utils/fetch.d.ts +41 -0
- package/dist/src/utils/fetch.js +155 -0
- package/dist/src/utils/fetch.js.map +1 -0
- package/dist/src/utils/file.d.ts +46 -0
- package/dist/src/utils/file.js +189 -0
- package/dist/src/utils/file.js.map +1 -0
- package/dist/src/utils/index.d.ts +11 -0
- package/dist/src/utils/index.js +29 -0
- package/dist/src/utils/index.js.map +1 -0
- package/dist/src/utils/logger.d.ts +161 -0
- package/dist/src/utils/logger.js +286 -0
- package/dist/src/utils/logger.js.map +1 -0
- package/dist/src/utils/performance.d.ts +98 -0
- package/dist/src/utils/performance.js +292 -0
- package/dist/src/utils/performance.js.map +1 -0
- package/dist/src/utils/retry.d.ts +56 -0
- package/dist/src/utils/retry.js +127 -0
- package/dist/src/utils/retry.js.map +1 -0
- package/package.json +61 -0
@@ -0,0 +1,237 @@
|
|
1
|
+
"use strict";
|
2
|
+
// Copied from src/info/user.ts
|
3
|
+
// Original file path: src/info/user.ts
|
4
|
+
/**
|
5
|
+
* 用戶影片獲取模組
|
6
|
+
* 提供獲取抖音用戶發布影片列表的功能
|
7
|
+
*/
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
9
|
+
exports.getOfficialVideoUrl = getOfficialVideoUrl;
|
10
|
+
exports.extractSecUserId = extractSecUserId;
|
11
|
+
exports.fetchUserVideos = fetchUserVideos;
|
12
|
+
const logger_1 = require("../../utils/logger");
|
13
|
+
const fetch_1 = require("../../utils/fetch"); // Import the general fetch utility
|
14
|
+
const error_handler_1 = require("./error-handler"); // Assuming this path is correct relative to the new location
|
15
|
+
/**
|
16
|
+
* 抖音 API 專用的 GET 請求函數
|
17
|
+
* @param url API URL
|
18
|
+
* @param params 查詢參數
|
19
|
+
* @param options 請求選項
|
20
|
+
* @returns Promise<any> API 響應
|
21
|
+
*/
|
22
|
+
async function douyinApiGet(url, params = {}, options = {}) {
|
23
|
+
// 構建完整的 URL,包含查詢參數
|
24
|
+
const queryString = new URLSearchParams(params).toString();
|
25
|
+
const fullUrl = `${url}${url.includes('?') ? '&' : '?'}${queryString}`;
|
26
|
+
// 使用通用的 getJson 函數發送請求
|
27
|
+
return await (0, fetch_1.getJson)(fullUrl, options);
|
28
|
+
}
|
29
|
+
/**
|
30
|
+
* 從 URL 列表中獲取官方影片下載地址
|
31
|
+
* @param urlList URL 列表
|
32
|
+
* @returns 官方影片下載地址
|
33
|
+
*/
|
34
|
+
function getOfficialVideoUrl(urlList) {
|
35
|
+
if (!urlList || urlList.length === 0)
|
36
|
+
return '';
|
37
|
+
// API返回的url_list通常包含多個URL,其中包含官方下載地址
|
38
|
+
// 檢查每個URL,返回官方格式的鏈接
|
39
|
+
for (const url of urlList) {
|
40
|
+
if (url.includes('douyin.com/aweme/v1/play')) {
|
41
|
+
return url;
|
42
|
+
}
|
43
|
+
}
|
44
|
+
// 如果沒有找到官方鏈接,則返回第一個鏈接作為後備
|
45
|
+
return urlList[0];
|
46
|
+
}
|
47
|
+
// 抖音用戶作品 API
|
48
|
+
const USER_POST_API = 'https://www.douyin.com/aweme/v1/web/aweme/post/';
|
49
|
+
// 抖音用戶喜歡作品 API
|
50
|
+
const USER_FAVORITE_API = 'https://www.douyin.com/aweme/v1/web/aweme/favorite/';
|
51
|
+
/**
|
52
|
+
* 從 URL 中提取用戶 ID (sec_uid)
|
53
|
+
* @param userUrl 用戶主頁 URL
|
54
|
+
* @returns 用戶 ID 或 null
|
55
|
+
*/
|
56
|
+
function extractSecUserId(userUrl) {
|
57
|
+
try {
|
58
|
+
// 嘗試從 URL 參數中提取
|
59
|
+
const urlObj = new URL(userUrl);
|
60
|
+
// Correct parameter name: sec_user_id instead of sec_uid
|
61
|
+
const secUid = urlObj.searchParams.get('sec_user_id');
|
62
|
+
// Removed temporary debug log
|
63
|
+
if (secUid) {
|
64
|
+
return secUid;
|
65
|
+
}
|
66
|
+
// 嘗試從路徑中提取
|
67
|
+
const pathMatch = userUrl.match(/\/user\/([^?/]+)/);
|
68
|
+
if (pathMatch && pathMatch[1]) {
|
69
|
+
return pathMatch[1];
|
70
|
+
}
|
71
|
+
logger_1.infoLogger.warn(`無法從 URL 中提取用戶 ID: ${userUrl}`);
|
72
|
+
return null;
|
73
|
+
}
|
74
|
+
catch (error) {
|
75
|
+
// Ensure the caught error is treated as an Error object for the logger
|
76
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
77
|
+
logger_1.infoLogger.error(`解析用戶 URL 失敗: ${userUrl}`, error instanceof Error ? error : new Error(errorMsg));
|
78
|
+
return null;
|
79
|
+
}
|
80
|
+
}
|
81
|
+
/**
|
82
|
+
* 獲取用戶影片分頁數據
|
83
|
+
* @param apiUrl API URL
|
84
|
+
* @param secUserId 用戶 ID
|
85
|
+
* @param cursor 分頁游標
|
86
|
+
* @param cookie Cookie 字串
|
87
|
+
* @returns Promise<{videos: UserVideoItem[], nextCursor: number, hasMore: boolean}>
|
88
|
+
*/
|
89
|
+
async function fetchUserVideoPage(apiUrl, secUserId, cursor, cookie) {
|
90
|
+
// 構建請求參數
|
91
|
+
const params = {
|
92
|
+
sec_user_id: secUserId,
|
93
|
+
count: 20, // 每頁數量
|
94
|
+
max_cursor: cursor,
|
95
|
+
aid: '6383',
|
96
|
+
version_code: '170400',
|
97
|
+
device_platform: 'webapp',
|
98
|
+
cookie_enabled: 'true'
|
99
|
+
};
|
100
|
+
// 帶 Cookie 的請求頭
|
101
|
+
const headers = {
|
102
|
+
'Cookie': cookie,
|
103
|
+
'Referer': apiUrl.includes('favorite')
|
104
|
+
? `https://www.douyin.com/user/${secUserId}?showTab=like`
|
105
|
+
: `https://www.douyin.com/user/${secUserId}`
|
106
|
+
};
|
107
|
+
// 使用重試機制發送請求
|
108
|
+
return await (0, error_handler_1.fetchWithRetry)(async () => {
|
109
|
+
try {
|
110
|
+
const response = await douyinApiGet(apiUrl, params, { headers });
|
111
|
+
// 檢查響應格式
|
112
|
+
if (!response.aweme_list || !Array.isArray(response.aweme_list)) {
|
113
|
+
throw new Error('獲取用戶影片列表失敗,響應數據格式異常');
|
114
|
+
}
|
115
|
+
// 檢查是否有錯誤信息
|
116
|
+
if (response.status_code && response.status_code !== 0) {
|
117
|
+
throw new Error(`獲取用戶影片失敗,狀態碼: ${response.status_code}, 信息: ${response.status_msg || '未知錯誤'}`);
|
118
|
+
}
|
119
|
+
// Use the defined AwemeItem type here
|
120
|
+
const videos = response.aweme_list.map((item) => {
|
121
|
+
const urlList = item.video?.play_addr?.url_list;
|
122
|
+
const videoPlayUrl = getOfficialVideoUrl(urlList); // Use helper to get a playable URL
|
123
|
+
return {
|
124
|
+
vid: item.aweme_id,
|
125
|
+
description: item.desc,
|
126
|
+
createTime: item.create_time,
|
127
|
+
videoPlayUrl: videoPlayUrl, // Assign the determined play URL
|
128
|
+
author: {
|
129
|
+
id: item.author?.sec_uid || item.author?.uid || '',
|
130
|
+
nickname: item.author?.nickname || '未知作者',
|
131
|
+
},
|
132
|
+
stats: {
|
133
|
+
playCount: item.statistics?.play_count,
|
134
|
+
likeCount: item.statistics?.digg_count, // digg_count 是點讚數
|
135
|
+
commentCount: item.statistics?.comment_count,
|
136
|
+
shareCount: item.statistics?.share_count,
|
137
|
+
},
|
138
|
+
};
|
139
|
+
});
|
140
|
+
return {
|
141
|
+
videos,
|
142
|
+
nextCursor: response.max_cursor,
|
143
|
+
hasMore: response.has_more === 1,
|
144
|
+
total: response.total
|
145
|
+
};
|
146
|
+
}
|
147
|
+
catch (error) {
|
148
|
+
// ... (error handling remains the same)
|
149
|
+
let statusCode;
|
150
|
+
let message;
|
151
|
+
if (typeof error === 'object' && error !== null) {
|
152
|
+
if ('response' in error && typeof error.response === 'object' && error.response !== null && 'status' in error.response) {
|
153
|
+
statusCode = error.response.status;
|
154
|
+
}
|
155
|
+
if ('message' in error && typeof error.message === 'string') {
|
156
|
+
message = error.message;
|
157
|
+
}
|
158
|
+
}
|
159
|
+
if (statusCode === 403 || (message && message.includes('403'))) {
|
160
|
+
logger_1.infoLogger.warn('無效的 Cookie 或權限不足,返回空列表');
|
161
|
+
return { videos: [], nextCursor: 0, hasMore: false };
|
162
|
+
}
|
163
|
+
throw error;
|
164
|
+
}
|
165
|
+
});
|
166
|
+
}
|
167
|
+
/**
|
168
|
+
* 獲取指定用戶的影片列表
|
169
|
+
* @param userUrl 用戶主頁 URL
|
170
|
+
* @param cookie 有效的抖音 Cookie
|
171
|
+
* @param limit 限制獲取的影片數量,0 表示獲取全部
|
172
|
+
* @param options 獲取選項
|
173
|
+
* @returns Promise<UserVideoItem[]> 用戶影片列表
|
174
|
+
*/
|
175
|
+
async function fetchUserVideos(userUrl, cookie, limit = 0, options = {}) {
|
176
|
+
// 確認 Cookie 是否提供
|
177
|
+
if (!cookie || cookie.trim() === '') {
|
178
|
+
logger_1.infoLogger.error('未提供有效的 Cookie,無法獲取用戶影片');
|
179
|
+
throw new Error('需要有效的抖音 Cookie 才能獲取用戶影片');
|
180
|
+
}
|
181
|
+
// 提取用戶 ID
|
182
|
+
const secUserId = extractSecUserId(userUrl);
|
183
|
+
if (!secUserId) {
|
184
|
+
throw new Error(`無法從 URL 提取用戶 ID: ${userUrl}`);
|
185
|
+
}
|
186
|
+
logger_1.infoLogger.info(`開始獲取用戶 (${secUserId}) 的影片列表`);
|
187
|
+
// 確定是獲取用戶發布的影片還是喜歡的影片
|
188
|
+
const isLikedVideos = userUrl.includes('/user') && userUrl.includes('showTab=like');
|
189
|
+
const apiUrl = isLikedVideos ? USER_FAVORITE_API : USER_POST_API;
|
190
|
+
// 初始化結果和游標
|
191
|
+
const results = [];
|
192
|
+
let cursor = 0;
|
193
|
+
let hasMore = true;
|
194
|
+
let totalEstimated;
|
195
|
+
try {
|
196
|
+
// 分頁獲取數據
|
197
|
+
while (hasMore && (limit === 0 || results.length < limit)) {
|
198
|
+
logger_1.infoLogger.debug(`獲取用戶影片列表頁,當前游標: ${cursor}`);
|
199
|
+
// 獲取單頁數據
|
200
|
+
const { videos, nextCursor, hasMore: hasMoreData, total } = await fetchUserVideoPage(apiUrl, secUserId, cursor, cookie);
|
201
|
+
// 如果獲取到了總數,更新估計總數
|
202
|
+
if (total !== undefined) {
|
203
|
+
totalEstimated = total;
|
204
|
+
}
|
205
|
+
// 添加到結果中
|
206
|
+
results.push(...videos);
|
207
|
+
// 更新進度
|
208
|
+
if (options.onProgress) {
|
209
|
+
options.onProgress(results.length, totalEstimated);
|
210
|
+
}
|
211
|
+
// 更新游標和是否還有更多
|
212
|
+
cursor = nextCursor;
|
213
|
+
hasMore = hasMoreData;
|
214
|
+
// 如果已達到限制,截斷結果
|
215
|
+
if (limit > 0 && results.length >= limit) {
|
216
|
+
results.splice(limit);
|
217
|
+
break;
|
218
|
+
}
|
219
|
+
// 如果沒有更多數據,結束循環
|
220
|
+
if (!hasMore) {
|
221
|
+
break;
|
222
|
+
}
|
223
|
+
// 短暫延遲防止請求過於頻繁
|
224
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
225
|
+
logger_1.infoLogger.debug(`已獲取 ${results.length} 個影片${totalEstimated ? `,總計約 ${totalEstimated} 個` : ''}`);
|
226
|
+
}
|
227
|
+
logger_1.infoLogger.info(`成功獲取用戶 (${secUserId}) 的影片列表,共 ${results.length} 個`);
|
228
|
+
return results;
|
229
|
+
}
|
230
|
+
catch (error) {
|
231
|
+
// 使用自定義錯誤處理函數
|
232
|
+
const enhancedError = (0, error_handler_1.handleDouyinApiError)(error);
|
233
|
+
logger_1.infoLogger.error(`獲取用戶影片列表失敗: ${enhancedError.message}`);
|
234
|
+
throw enhancedError;
|
235
|
+
}
|
236
|
+
}
|
237
|
+
//# sourceMappingURL=user.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"user.js","sourceRoot":"","sources":["../../../../src/douyin/info/user.ts"],"names":[],"mappings":"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"}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
/**
|
2
|
+
* 抖音連結檢查模組
|
3
|
+
* 檢查文本是否包含抖音連結
|
4
|
+
*
|
5
|
+
* @remarks
|
6
|
+
* 參考來源:此功能改寫自原本存放於 src/parser/extract-links.ts 的功能
|
7
|
+
* 需要驗證:確認函數是否與最新的抖音 URL 格式相容
|
8
|
+
*/
|
9
|
+
/**
|
10
|
+
* 檢查文本是否包含抖音連結
|
11
|
+
* @param text 要檢查的文本
|
12
|
+
* @returns true 如果包含抖音連結,否則 false
|
13
|
+
*
|
14
|
+
* @remarks
|
15
|
+
* 改寫自原本存放於 src/parser/extract-links.ts 的功能
|
16
|
+
* 簡單封裝了 extractDouyinLinks 函數的結果檢查
|
17
|
+
*/
|
18
|
+
export declare function containsDouyinLink(text: string): boolean;
|
@@ -0,0 +1,27 @@
|
|
1
|
+
"use strict";
|
2
|
+
/**
|
3
|
+
* 抖音連結檢查模組
|
4
|
+
* 檢查文本是否包含抖音連結
|
5
|
+
*
|
6
|
+
* @remarks
|
7
|
+
* 參考來源:此功能改寫自原本存放於 src/parser/extract-links.ts 的功能
|
8
|
+
* 需要驗證:確認函數是否與最新的抖音 URL 格式相容
|
9
|
+
*/
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
11
|
+
exports.containsDouyinLink = containsDouyinLink;
|
12
|
+
const extractDouyinLinks_1 = require("./extractDouyinLinks");
|
13
|
+
/**
|
14
|
+
* 檢查文本是否包含抖音連結
|
15
|
+
* @param text 要檢查的文本
|
16
|
+
* @returns true 如果包含抖音連結,否則 false
|
17
|
+
*
|
18
|
+
* @remarks
|
19
|
+
* 改寫自原本存放於 src/parser/extract-links.ts 的功能
|
20
|
+
* 簡單封裝了 extractDouyinLinks 函數的結果檢查
|
21
|
+
*/
|
22
|
+
function containsDouyinLink(text) {
|
23
|
+
// 利用 extractDouyinLinks 函數提取連結,檢查是否有結果
|
24
|
+
const links = (0, extractDouyinLinks_1.extractDouyinLinks)(text);
|
25
|
+
return links.length > 0;
|
26
|
+
}
|
27
|
+
//# sourceMappingURL=containsDouyinLink.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"containsDouyinLink.js","sourceRoot":"","sources":["../../../../src/douyin/parser/containsDouyinLink.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;AAaH,gDAIC;AAfD,6DAA0D;AAE1D;;;;;;;;GAQG;AACH,SAAgB,kBAAkB,CAAC,IAAY;IAC7C,uCAAuC;IACvC,MAAM,KAAK,GAAG,IAAA,uCAAkB,EAAC,IAAI,CAAC,CAAC;IACvC,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;AAC1B,CAAC"}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
/**
|
2
|
+
* 連結提取模組
|
3
|
+
* 從文本中提取抖音連結
|
4
|
+
*/
|
5
|
+
/**
|
6
|
+
* 從文本中提取所有潛在的抖音連結
|
7
|
+
* @param text 包含抖音連結的文本
|
8
|
+
* @returns string[] 提取出的抖音連結陣列
|
9
|
+
*/
|
10
|
+
export declare function extractDouyinLinks(text: string): string[];
|
11
|
+
/**
|
12
|
+
* 從文本中提取特定類型的抖音連結
|
13
|
+
* @param text 包含抖音連結的文本
|
14
|
+
* @param typeName 連結類型名稱 (如 'standard', 'short' 等)
|
15
|
+
* @returns string[] 提取出的指定類型抖音連結陣列
|
16
|
+
*/
|
17
|
+
export declare function extractDouyinLinksByType(text: string, typeName: string): string[];
|
18
|
+
/**
|
19
|
+
* 檢查文本是否包含抖音連結
|
20
|
+
* @param text 要檢查的文本
|
21
|
+
* @returns boolean 是否包含抖音連結
|
22
|
+
*/
|
23
|
+
export declare function containsDouyinLink(text: string): boolean;
|
@@ -0,0 +1,79 @@
|
|
1
|
+
"use strict";
|
2
|
+
// Copied from src/parser/extract-links.ts
|
3
|
+
// Original file path: src/parser/extract-links.ts
|
4
|
+
/**
|
5
|
+
* 連結提取模組
|
6
|
+
* 從文本中提取抖音連結
|
7
|
+
*/
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
9
|
+
exports.extractDouyinLinks = extractDouyinLinks;
|
10
|
+
exports.extractDouyinLinksByType = extractDouyinLinksByType;
|
11
|
+
exports.containsDouyinLink = containsDouyinLink;
|
12
|
+
const logger_1 = require("../../utils/logger"); // Updated path to shared utils logger
|
13
|
+
const link_patterns_1 = require("./link-patterns");
|
14
|
+
/**
|
15
|
+
* 從文本中提取所有潛在的抖音連結
|
16
|
+
* @param text 包含抖音連結的文本
|
17
|
+
* @returns string[] 提取出的抖音連結陣列
|
18
|
+
*/
|
19
|
+
function extractDouyinLinks(text) {
|
20
|
+
if (!text || typeof text !== 'string') {
|
21
|
+
logger_1.parserLogger.warn('提取連結時收到無效文本');
|
22
|
+
return [];
|
23
|
+
}
|
24
|
+
// 使用合併正則表達式提取所有可能的抖音連結
|
25
|
+
const combinedPattern = (0, link_patterns_1.createCombinedPattern)();
|
26
|
+
const matches = text.match(combinedPattern);
|
27
|
+
// 如果沒有找到任何連結,返回空陣列
|
28
|
+
if (!matches) {
|
29
|
+
logger_1.parserLogger.debug('文本中未找到抖音連結');
|
30
|
+
return [];
|
31
|
+
}
|
32
|
+
// 過濾重複連結
|
33
|
+
const uniqueUrls = Array.from(new Set(matches));
|
34
|
+
logger_1.parserLogger.debug(`從文本中提取到 ${uniqueUrls.length} 個唯一抖音連結`);
|
35
|
+
return uniqueUrls;
|
36
|
+
}
|
37
|
+
/**
|
38
|
+
* 從文本中提取特定類型的抖音連結
|
39
|
+
* @param text 包含抖音連結的文本
|
40
|
+
* @param typeName 連結類型名稱 (如 'standard', 'short' 等)
|
41
|
+
* @returns string[] 提取出的指定類型抖音連結陣列
|
42
|
+
*/
|
43
|
+
function extractDouyinLinksByType(text, typeName) {
|
44
|
+
if (!text || typeof text !== 'string') {
|
45
|
+
logger_1.parserLogger.warn('提取連結時收到無效文本');
|
46
|
+
return [];
|
47
|
+
}
|
48
|
+
// 查找指定類型的模式
|
49
|
+
const pattern = link_patterns_1.DOUYIN_LINK_PATTERNS.find(p => p.name === typeName);
|
50
|
+
if (!pattern) {
|
51
|
+
logger_1.parserLogger.warn(`未知的連結類型: ${typeName}`);
|
52
|
+
return [];
|
53
|
+
}
|
54
|
+
// 創建能夠全局匹配的正則表達式
|
55
|
+
const globalPattern = new RegExp(pattern.pattern.source, 'g');
|
56
|
+
const matches = text.match(globalPattern);
|
57
|
+
// 如果沒有找到任何連結,返回空陣列
|
58
|
+
if (!matches) {
|
59
|
+
logger_1.parserLogger.debug(`文本中未找到類型為 ${typeName} 的抖音連結`);
|
60
|
+
return [];
|
61
|
+
}
|
62
|
+
// 過濾重複連結
|
63
|
+
const uniqueUrls = Array.from(new Set(matches));
|
64
|
+
logger_1.parserLogger.debug(`從文本中提取到 ${uniqueUrls.length} 個類型為 ${typeName} 的唯一抖音連結`);
|
65
|
+
return uniqueUrls;
|
66
|
+
}
|
67
|
+
/**
|
68
|
+
* 檢查文本是否包含抖音連結
|
69
|
+
* @param text 要檢查的文本
|
70
|
+
* @returns boolean 是否包含抖音連結
|
71
|
+
*/
|
72
|
+
function containsDouyinLink(text) {
|
73
|
+
if (!text || typeof text !== 'string') {
|
74
|
+
return false;
|
75
|
+
}
|
76
|
+
const combinedPattern = (0, link_patterns_1.createCombinedPattern)();
|
77
|
+
return combinedPattern.test(text);
|
78
|
+
}
|
79
|
+
//# sourceMappingURL=extract-links.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"extract-links.js","sourceRoot":"","sources":["../../../../src/douyin/parser/extract-links.ts"],"names":[],"mappings":";AAAA,0CAA0C;AAC1C,kDAAkD;AAClD;;;GAGG;;AAUH,gDAqBC;AAQD,4DA4BC;AAOD,gDAOC;AA/ED,+CAA4D,CAAC,sCAAsC;AACnG,mDAA8E;AAE9E;;;;GAIG;AACH,SAAgB,kBAAkB,CAAC,IAAY;IAC7C,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtC,qBAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC3B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,uBAAuB;IACvB,MAAM,eAAe,GAAG,IAAA,qCAAqB,GAAE,CAAC;IAChD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;IAE5C,mBAAmB;IACnB,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,qBAAM,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QAC3B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,SAAS;IACT,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;IAChD,qBAAM,CAAC,KAAK,CAAC,WAAW,UAAU,CAAC,MAAM,UAAU,CAAC,CAAC;IAErD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;;GAKG;AACH,SAAgB,wBAAwB,CAAC,IAAY,EAAE,QAAgB;IACrE,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtC,qBAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC3B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,YAAY;IACZ,MAAM,OAAO,GAAG,oCAAoB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;IACpE,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,qBAAM,CAAC,IAAI,CAAC,YAAY,QAAQ,EAAE,CAAC,CAAC;QACpC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,iBAAiB;IACjB,MAAM,aAAa,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9D,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;IAE1C,mBAAmB;IACnB,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,qBAAM,CAAC,KAAK,CAAC,aAAa,QAAQ,QAAQ,CAAC,CAAC;QAC5C,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,SAAS;IACT,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;IAChD,qBAAM,CAAC,KAAK,CAAC,WAAW,UAAU,CAAC,MAAM,SAAS,QAAQ,UAAU,CAAC,CAAC;IAEtE,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;GAIG;AACH,SAAgB,kBAAkB,CAAC,IAAY;IAC7C,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,eAAe,GAAG,IAAA,qCAAqB,GAAE,CAAC;IAChD,OAAO,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACpC,CAAC"}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
/**
|
2
|
+
* 抖音連結提取模組
|
3
|
+
* 從文本中提取抖音連結
|
4
|
+
*
|
5
|
+
* @remarks
|
6
|
+
* 參考來源:此功能改寫自原本存放於 src/parser/extract-links.ts 的功能
|
7
|
+
* 需要驗證:正則表達式是否匹配最新的抖音 URL 格式
|
8
|
+
*/
|
9
|
+
/**
|
10
|
+
* 從文本中提取抖音連結
|
11
|
+
* @param text 可能包含抖音連結的文本
|
12
|
+
* @returns 提取出的抖音連結陣列
|
13
|
+
*
|
14
|
+
* @remarks
|
15
|
+
* 改寫自原本存放於 src/parser/extract-links.ts 的功能
|
16
|
+
* 使用正則表達式匹配不同的抖音網址格式
|
17
|
+
*/
|
18
|
+
export declare function extractDouyinLinks(text: string): string[];
|
@@ -0,0 +1,58 @@
|
|
1
|
+
"use strict";
|
2
|
+
/**
|
3
|
+
* 抖音連結提取模組
|
4
|
+
* 從文本中提取抖音連結
|
5
|
+
*
|
6
|
+
* @remarks
|
7
|
+
* 參考來源:此功能改寫自原本存放於 src/parser/extract-links.ts 的功能
|
8
|
+
* 需要驗證:正則表達式是否匹配最新的抖音 URL 格式
|
9
|
+
*/
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
11
|
+
exports.extractDouyinLinks = extractDouyinLinks;
|
12
|
+
/**
|
13
|
+
* 抖音 URL 正則表達式模式
|
14
|
+
*/
|
15
|
+
const PATTERNS = [
|
16
|
+
// 標準網頁連結,例如: https://www.douyin.com/video/7123456789
|
17
|
+
/https?:\/\/(?:www\.)?douyin\.com\/video\/(\d+)/g,
|
18
|
+
// 短連結,例如: https://v.douyin.com/abc123/
|
19
|
+
/https?:\/\/v\.douyin\.com\/([a-zA-Z0-9-]+)\/?/g,
|
20
|
+
// 移動端分享連結,例如: https://www.douyin.com/share/video/123456789
|
21
|
+
/https?:\/\/(?:www\.)?douyin\.com\/share\/video\/(\d+)/g,
|
22
|
+
// 筆記類型連結,例如: https://www.douyin.com/note/123456789
|
23
|
+
/https?:\/\/(?:www\.)?douyin\.com\/note\/(\d+)/g,
|
24
|
+
// 發現頁連結,例如: https://www.douyin.com/discover?modal_id=7123456789
|
25
|
+
/https?:\/\/(?:www\.)?douyin\.com\/discover\?.*modal_id=(\d+)/g,
|
26
|
+
// 帶參數的移動端連結,例如: https://www.iesdouyin.com/share/video/xxx/?region=CN&...
|
27
|
+
/https?:\/\/(?:www\.)?(?:douyin|iesdouyin)\.com\/.*\/.*\?.*(?:video_id|vid)=([^&]+)/g
|
28
|
+
// https://www.douyin.com/?vid=7489881436611218751&recommend=1
|
29
|
+
// /https?:\/\/(?:www\.)?douyin\.com\/\?.*vid=(\d+)/g,
|
30
|
+
];
|
31
|
+
/**
|
32
|
+
* 從文本中提取抖音連結
|
33
|
+
* @param text 可能包含抖音連結的文本
|
34
|
+
* @returns 提取出的抖音連結陣列
|
35
|
+
*
|
36
|
+
* @remarks
|
37
|
+
* 改寫自原本存放於 src/parser/extract-links.ts 的功能
|
38
|
+
* 使用正則表達式匹配不同的抖音網址格式
|
39
|
+
*/
|
40
|
+
function extractDouyinLinks(text) {
|
41
|
+
if (!text)
|
42
|
+
return [];
|
43
|
+
// 使用所有模式匹配文本
|
44
|
+
const results = [];
|
45
|
+
for (const pattern of PATTERNS) {
|
46
|
+
const matches = text.match(pattern);
|
47
|
+
if (matches) {
|
48
|
+
for (const match of matches) {
|
49
|
+
// 避免重複添加
|
50
|
+
if (!results.includes(match)) {
|
51
|
+
results.push(match);
|
52
|
+
}
|
53
|
+
}
|
54
|
+
}
|
55
|
+
}
|
56
|
+
return results;
|
57
|
+
}
|
58
|
+
//# sourceMappingURL=extractDouyinLinks.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"extractDouyinLinks.js","sourceRoot":"","sources":["../../../../src/douyin/parser/extractDouyinLinks.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;AAoCH,gDAkBC;AApDD;;GAEG;AACH,MAAM,QAAQ,GAAG;IACf,qDAAqD;IACrD,iDAAiD;IAEjD,uCAAuC;IACvC,gDAAgD;IAEhD,2DAA2D;IAC3D,wDAAwD;IAExD,mDAAmD;IACnD,gDAAgD;IAEhD,gEAAgE;IAChE,+DAA+D;IAE/D,yEAAyE;IACzE,qFAAqF;IACrF,+DAA+D;IAC/D,sDAAsD;CACvD,CAAC;AAEF;;;;;;;;GAQG;AACH,SAAgB,kBAAkB,CAAC,IAAY;IAC7C,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IAErB,aAAa;IACb,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACpC,IAAI,OAAO,EAAE,CAAC;YACZ,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC5B,SAAS;gBACT,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;oBAC7B,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACtB,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
@@ -0,0 +1,35 @@
|
|
1
|
+
/**
|
2
|
+
* 連結解析模組
|
3
|
+
* 提供解析抖音各種格式連結的功能
|
4
|
+
*/
|
5
|
+
import { ParseResult, ParseOptions } from '../../types';
|
6
|
+
import { extractDouyinLinks, containsDouyinLink } from './extract-links';
|
7
|
+
import { resolveLink, resolveShortUrl, createStandardUrl } from './resolve-links';
|
8
|
+
import { parseBatch, parseBatchWithStats } from './parse-batch';
|
9
|
+
import { getLinkType, extractVideoId } from './link-patterns';
|
10
|
+
export { extractDouyinLinks, containsDouyinLink, resolveLink, resolveShortUrl, parseBatch, parseBatchWithStats, getLinkType, extractVideoId, createStandardUrl };
|
11
|
+
/**
|
12
|
+
* 將單個抖音連結標準化
|
13
|
+
* @param url 抖音連結
|
14
|
+
* @returns Promise<ParseResult | null> 解析結果或 null
|
15
|
+
*/
|
16
|
+
export declare function standardizeDouyinUrl(url: string): Promise<ParseResult | null>;
|
17
|
+
/**
|
18
|
+
* 解析抖音短連結並獲取標準 URL
|
19
|
+
* @param shortUrl 抖音短連結
|
20
|
+
* @returns Promise<string | null> 標準抖音影片 URL 或 null
|
21
|
+
*/
|
22
|
+
export declare function parseDouyinShortUrl(shortUrl: string): Promise<string | null>;
|
23
|
+
/**
|
24
|
+
* 從文本中提取抖音連結
|
25
|
+
* @param text 包含抖音連結的文本
|
26
|
+
* @returns string[] 提取出的抖音連結陣列
|
27
|
+
*/
|
28
|
+
export declare function extractDouyinUrls(text: string): string[];
|
29
|
+
/**
|
30
|
+
* 從文本中解析抖音連結,支援多種格式(標準URL、短連結、移動端分享連結等),並將其標準化。
|
31
|
+
* @param text 包含一個或多個抖音連結的文本字串
|
32
|
+
* @param options 解析選項
|
33
|
+
* @returns Promise<ParseResult[]> 解析結果陣列
|
34
|
+
*/
|
35
|
+
export declare function parseDouyinLinks(text: string, options?: ParseOptions): Promise<ParseResult[]>;
|
@@ -0,0 +1,70 @@
|
|
1
|
+
"use strict";
|
2
|
+
// Copied from src/parser/index.ts
|
3
|
+
// Original file path: src/parser/index.ts
|
4
|
+
/**
|
5
|
+
* 連結解析模組
|
6
|
+
* 提供解析抖音各種格式連結的功能
|
7
|
+
*/
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
9
|
+
exports.createStandardUrl = exports.extractVideoId = exports.getLinkType = exports.parseBatchWithStats = exports.parseBatch = exports.resolveShortUrl = exports.resolveLink = exports.containsDouyinLink = exports.extractDouyinLinks = void 0;
|
10
|
+
exports.standardizeDouyinUrl = standardizeDouyinUrl;
|
11
|
+
exports.parseDouyinShortUrl = parseDouyinShortUrl;
|
12
|
+
exports.extractDouyinUrls = extractDouyinUrls;
|
13
|
+
exports.parseDouyinLinks = parseDouyinLinks;
|
14
|
+
const logger_1 = require("../../utils/logger"); // Updated path to shared utils logger
|
15
|
+
const extract_links_1 = require("./extract-links");
|
16
|
+
Object.defineProperty(exports, "extractDouyinLinks", { enumerable: true, get: function () { return extract_links_1.extractDouyinLinks; } });
|
17
|
+
Object.defineProperty(exports, "containsDouyinLink", { enumerable: true, get: function () { return extract_links_1.containsDouyinLink; } });
|
18
|
+
const resolve_links_1 = require("./resolve-links");
|
19
|
+
Object.defineProperty(exports, "resolveLink", { enumerable: true, get: function () { return resolve_links_1.resolveLink; } });
|
20
|
+
Object.defineProperty(exports, "resolveShortUrl", { enumerable: true, get: function () { return resolve_links_1.resolveShortUrl; } });
|
21
|
+
Object.defineProperty(exports, "createStandardUrl", { enumerable: true, get: function () { return resolve_links_1.createStandardUrl; } });
|
22
|
+
const parse_batch_1 = require("./parse-batch");
|
23
|
+
Object.defineProperty(exports, "parseBatch", { enumerable: true, get: function () { return parse_batch_1.parseBatch; } });
|
24
|
+
Object.defineProperty(exports, "parseBatchWithStats", { enumerable: true, get: function () { return parse_batch_1.parseBatchWithStats; } });
|
25
|
+
const link_patterns_1 = require("./link-patterns");
|
26
|
+
Object.defineProperty(exports, "getLinkType", { enumerable: true, get: function () { return link_patterns_1.getLinkType; } });
|
27
|
+
Object.defineProperty(exports, "extractVideoId", { enumerable: true, get: function () { return link_patterns_1.extractVideoId; } });
|
28
|
+
/**
|
29
|
+
* 將單個抖音連結標準化
|
30
|
+
* @param url 抖音連結
|
31
|
+
* @returns Promise<ParseResult | null> 解析結果或 null
|
32
|
+
*/
|
33
|
+
async function standardizeDouyinUrl(url) {
|
34
|
+
return await (0, resolve_links_1.resolveLink)(url);
|
35
|
+
}
|
36
|
+
/**
|
37
|
+
* 解析抖音短連結並獲取標準 URL
|
38
|
+
* @param shortUrl 抖音短連結
|
39
|
+
* @returns Promise<string | null> 標準抖音影片 URL 或 null
|
40
|
+
*/
|
41
|
+
async function parseDouyinShortUrl(shortUrl) {
|
42
|
+
return await (0, resolve_links_1.resolveShortUrl)(shortUrl);
|
43
|
+
}
|
44
|
+
/**
|
45
|
+
* 從文本中提取抖音連結
|
46
|
+
* @param text 包含抖音連結的文本
|
47
|
+
* @returns string[] 提取出的抖音連結陣列
|
48
|
+
*/
|
49
|
+
function extractDouyinUrls(text) {
|
50
|
+
return (0, extract_links_1.extractDouyinLinks)(text);
|
51
|
+
}
|
52
|
+
/**
|
53
|
+
* 從文本中解析抖音連結,支援多種格式(標準URL、短連結、移動端分享連結等),並將其標準化。
|
54
|
+
* @param text 包含一個或多個抖音連結的文本字串
|
55
|
+
* @param options 解析選項
|
56
|
+
* @returns Promise<ParseResult[]> 解析結果陣列
|
57
|
+
*/
|
58
|
+
async function parseDouyinLinks(text, options = {}) {
|
59
|
+
// 提取連結
|
60
|
+
const urls = (0, extract_links_1.extractDouyinLinks)(text);
|
61
|
+
logger_1.parserLogger.info(`從文本中找到 ${urls.length} 個抖音連結`);
|
62
|
+
if (urls.length === 0) {
|
63
|
+
logger_1.parserLogger.warn('未找到任何抖音連結');
|
64
|
+
return [];
|
65
|
+
}
|
66
|
+
// 並行解析所有連結
|
67
|
+
const results = await (0, parse_batch_1.parseBatch)(urls, options);
|
68
|
+
return results;
|
69
|
+
}
|
70
|
+
//# sourceMappingURL=index.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/douyin/parser/index.ts"],"names":[],"mappings":";AAAA,kCAAkC;AAClC,0CAA0C;AAC1C;;;GAGG;;;AA0BH,oDAEC;AAOD,kDAEC;AAOD,8CAEC;AAQD,4CAiBC;AArED,+CAA4D,CAAC,sCAAsC;AAEnG,mDAAyE;AAMvE,mGANO,kCAAkB,OAMP;AAClB,mGAP2B,kCAAkB,OAO3B;AANpB,mDAAkF;AAOhF,4FAPO,2BAAW,OAOP;AACX,gGARoB,+BAAe,OAQpB;AAKf,kGAbqC,iCAAiB,OAarC;AAZnB,+CAAgE;AAQ9D,2FARO,wBAAU,OAQP;AACV,oGATmB,iCAAmB,OASnB;AARrB,mDAA8D;AAS5D,4FATO,2BAAW,OASP;AACX,+FAVoB,8BAAc,OAUpB;AAIhB;;;;GAIG;AACI,KAAK,UAAU,oBAAoB,CAAC,GAAW;IACpD,OAAO,MAAM,IAAA,2BAAW,EAAC,GAAG,CAAC,CAAC;AAChC,CAAC;AAED;;;;GAIG;AACI,KAAK,UAAU,mBAAmB,CAAC,QAAgB;IACxD,OAAO,MAAM,IAAA,+BAAe,EAAC,QAAQ,CAAC,CAAC;AACzC,CAAC;AAED;;;;GAIG;AACH,SAAgB,iBAAiB,CAAC,IAAY;IAC5C,OAAO,IAAA,kCAAkB,EAAC,IAAI,CAAC,CAAC;AAClC,CAAC;AAED;;;;;GAKG;AACI,KAAK,UAAU,gBAAgB,CACpC,IAAY,EACZ,UAAwB,EAAE;IAE1B,OAAO;IACP,MAAM,IAAI,GAAG,IAAA,kCAAkB,EAAC,IAAI,CAAC,CAAC;IACtC,qBAAM,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,MAAM,QAAQ,CAAC,CAAC;IAE3C,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,qBAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACzB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,WAAW;IACX,MAAM,OAAO,GAAG,MAAM,IAAA,wBAAU,EAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAEhD,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
@@ -0,0 +1,34 @@
|
|
1
|
+
/**
|
2
|
+
* 抖音連結模式定義
|
3
|
+
* 定義各種抖音連結的正則表達式和處理方式
|
4
|
+
*/
|
5
|
+
/**
|
6
|
+
* 連結模式介面
|
7
|
+
*/
|
8
|
+
export interface LinkPattern {
|
9
|
+
name: string;
|
10
|
+
pattern: RegExp;
|
11
|
+
needsRedirect: boolean;
|
12
|
+
}
|
13
|
+
/**
|
14
|
+
* 抖音連結模式陣列
|
15
|
+
* 包含各種可能的抖音連結格式
|
16
|
+
*/
|
17
|
+
export declare const DOUYIN_LINK_PATTERNS: LinkPattern[];
|
18
|
+
/**
|
19
|
+
* 創建用於在文本中查找所有抖音連結的正則表達式
|
20
|
+
* @returns RegExp 可以匹配任何抖音連結的正則表達式
|
21
|
+
*/
|
22
|
+
export declare function createCombinedPattern(): RegExp;
|
23
|
+
/**
|
24
|
+
* 獲取抖音連結的類型
|
25
|
+
* @param url 抖音連結
|
26
|
+
* @returns LinkPattern | null 連結類型或 null (如果不匹配任何類型)
|
27
|
+
*/
|
28
|
+
export declare function getLinkType(url: string): LinkPattern | null;
|
29
|
+
/**
|
30
|
+
* 從 URL 中提取影片 ID (如果可能)
|
31
|
+
* @param url 抖音連結
|
32
|
+
* @returns string | null 影片 ID 或 null (如果無法提取)
|
33
|
+
*/
|
34
|
+
export declare function extractVideoId(url: string): string | null;
|