@xbibzlibrary/tiktokscrap
Version:
Powerful TikTok Scraper and Downloader Library
119 lines (107 loc) • 3.4 kB
text/typescript
import BaseDownloader from './base';
import { TikTokPhoto, TikTokDownloadOptions, TikTokScrapResult } from '../types';
import path from 'path';
export class PhotoDownloader extends BaseDownloader {
public async downloadPhoto(
photo: TikTokPhoto,
options: TikTokDownloadOptions = {}
): Promise<TikTokScrapResult<string[]>> {
return this.executeDownload(async () => {
const { outputDir = './downloads', filename } = options;
if (!photo.covers || photo.covers.length === 0) {
throw new Error('Photo URLs not available');
}
const downloadPromises = photo.covers.map((cover, index) => {
const photoFilename = this.generateFilename(
cover.url,
'.jpg',
filename ? { filename: `${filename}_${index + 1}` } : undefined
);
const outputPath = this.getOutputPath(outputDir, photoFilename);
return this.downloadFile(cover.url, outputPath, options);
});
return Promise.all(downloadPromises);
}, `Download photo: ${photo.id}`);
}
public async downloadPhotoByUrl(
url: string,
options: TikTokDownloadOptions = {}
): Promise<TikTokScrapResult<string[]>> {
return this.executeDownload(async () => {
// This would require importing the PhotoScraper, but to avoid circular dependencies,
// we'll assume the URL is valid and extract the photo ID
const photoId = this.extractPhotoIdFromUrl(url);
if (!photoId) {
throw new Error('Could not extract photo ID from URL');
}
// In a real implementation, you would use the PhotoScraper to get the photo data
// For now, we'll construct a minimal photo object with the URL
const photo: TikTokPhoto = {
id: photoId,
text: '',
createTime: 0,
author: {
id: '',
uniqueId: '',
nickname: '',
avatarUrl: '',
signature: '',
verified: false,
following: 0,
fans: 0,
heart: 0,
video: 0,
digg: 0,
privateAccount: false,
isSecret: false,
secUid: ''
},
music: {
id: '',
title: '',
author: '',
album: '',
playUrl: '',
coverLarge: '',
coverMedium: '',
coverThumb: '',
duration: 0
},
stats: {
digg: 0,
share: 0,
comment: 0,
play: 0
},
covers: [{
url,
width: 0,
height: 0
}],
webVideoUrl: url,
hashtags: [],
mentions: [],
effects: [],
isAd: false,
commentsDisabled: false,
duetEnabled: false,
stitchEnabled: false,
secret: false,
forFriend: false,
digged: false,
itemCommentStatus: 0
};
const result = await this.downloadPhoto(photo, options);
if (result.success && result.data) {
return result.data;
} else {
throw new Error(result.error || 'Failed to download photo by URL');
}
}, `Download photo by URL: ${url}`);
}
private extractPhotoIdFromUrl(url: string): string | null {
const match = url.match(/\/photo\/(\d+)/);
return match ? match[1] : null;
}
}
export default PhotoDownloader;