Skip to content

Commit

Permalink
feat(route): toutiao video (DIYgod#17479)
Browse files Browse the repository at this point in the history
  • Loading branch information
TonyRL authored Nov 6, 2024
1 parent 9856a2a commit 2d1c6cc
Show file tree
Hide file tree
Showing 3 changed files with 199 additions and 20 deletions.
7 changes: 7 additions & 0 deletions lib/routes/toutiao/templates/video.art
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<video controls preload="metadata"
{{ if poster }}
poster="{{ poster }}"
{{ /if }}
>
<source src="{{ url }}" type="video/mp4" />
</video>
133 changes: 126 additions & 7 deletions lib/routes/toutiao/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,19 @@ export interface Feed {
cell_ctrls: CellCtrls;
cell_flag: number;
cell_layout_style: number;
/**
* 0: video
* 32: text (w)
* 49: video
* 60: article
*/
cell_type: number;
comment_count: number;
common_raw_data: string;
/**
* Appears only if cell_type is 32
*/
content?: string;
content: string;
content_decoration: string;
control_meta: ControlMeta;
cursor: number;
Expand Down Expand Up @@ -55,7 +61,7 @@ export interface Feed {
/**
* Appears only if cell_type is 32
*/
rich_content?: string;
rich_content: string;
read_count: number;
reback_flag: number;
repin_count: number;
Expand All @@ -70,15 +76,22 @@ export interface Feed {
title: string;
url: string;
/**
* Appears only if cell_type is 32
* Appears only if cell_type is 32, 49(0)
*/
user?: UserInfo;
user: UserInfoCell32 | UserInfoCell49;
user_bury: number;
user_digg: number;
user_info?: UserInfo;
/**
* Appears only if cell_type is 0, 60
*/
user_info: UserInfoCell60;
user_like: number;
user_repin: number;
user_repin_time: number;
/**
* Appears only if cell_type is 0, 49
*/
video: Video;
video_duration: number;
video_style: number;
image_list: ImageListItem[];
Expand Down Expand Up @@ -251,6 +264,62 @@ interface UserInteraction {

type VideoInfo = unknown;

interface Video {
bitrate: number;
codec_type: string;
definition: string;
download_addr: DownloadAddr;
duration: number;
encode_user_tag: string;
file_hash: string;
height: number;
origin_cover: OriginCover;
play_addr: PlayAddr;
play_addr_list: PlayAddrListItem[];
ratio: string;
size: number;
url_expire: number;
video_id: string;
volume: Volume;
vtype: string;
width: number;
}

interface DownloadAddr {
uri: string;
url_list: string[];
}

interface OriginCover {
uri: string;
url_list: string[];
}

interface PlayAddr {
uri: string;
url_list: string[];
}

interface PlayAddrListItem {
bitrate: number;
codec_type: string;
definition: string;
encode_user_tag: string;
file_hash: string;
play_url_list: string[];
quality: string;
size: number;
url_expire: number;
video_quality: number;
volume: Volume;
vtype: string;
}

interface Volume {
Loudness: number;
Peak: number;
}

interface LogPb {
cell_layout_style: string;
group_id_str: string;
Expand All @@ -267,10 +336,60 @@ interface ShowMore {
url: string;
}

interface UserInfo {
interface UserInfoCell32 {
avatar_url: string;
description: string;
desc: string;
id: number;
is_blocked: number;
is_blocking: number;
is_followed: number;
is_following: number;
is_friend: number;
live_info_type: number;
medals: unknown;
name: string;
remark_name: string;
schema: string;
screen_name: string;
theme_day: string;
user_auth_info: string;
user_decoration: string;
user_id: string;
user_verified: number;
verified_content: string;
}

interface UserInfoCell49 {
info: {
avatar_uri: string;
avatar_url: string;
ban_status: boolean;
desc: string;
media_id: string;
name: string;
origin_profile_url: boolean;
origin_user_id: string;
schema: string;
user_auth_info: string;
user_id: string;
user_verified: number;
verified_content: string;
};
relation: {
is_followed: number;
is_following: number;
is_friend: number;
};
relation_count: {
followers_count: number;
following_count: number;
};
user_id: string;
}

interface UserInfoCell60 {
avatar_url: string;
description: string;
follow: boolean;
name: string;
user_auth_info: string;
Expand Down
79 changes: 66 additions & 13 deletions lib/routes/toutiao/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ import { generate_a_bogus } from './a-bogus';
import { Feed } from './types';
import RejectError from '@/errors/types/reject';
import { config } from '@/config';
import path from 'node:path';
import { getCurrentPath } from '@/utils/helpers';
import { art } from '@/utils/render';

const __dirname = getCurrentPath(import.meta.url);

export const route: Route = {
path: '/user/token/:token',
Expand Down Expand Up @@ -52,23 +57,71 @@ async function handler(ctx) {
}

const items = feed.map((item) => {
const enclosure = item.large_image_list?.pop();
return {
title: item.title,
description: item.rich_content ?? item.abstract ?? item.content,
link: `https://www.toutiao.com/${item.cell_type === 60 ? 'article' : /* 32 */ 'w'}/${item.id}/`,
pubDate: parseDate(item.publish_time, 'X'),
author: item.user_info?.name ?? item.user?.name ?? item.source,
enclosure_url: enclosure?.url,
enclosure_type: enclosure?.url ? `image/${new URL(enclosure.url).pathname.split('.').pop()}` : undefined,
};
switch (item.cell_type) {
case 0:
case 49: {
const video = item.video.play_addr_list.sort((a, b) => b.bitrate - a.bitrate)[0];
return {
title: item.title,
description: art(path.join(__dirname, 'templates', 'video.art'), {
poster: item.video.origin_cover.url_list[0],
url: item.video.play_addr_list.sort((a, b) => b.bitrate - a.bitrate)[0].play_url_list[0],
}),
link: `https://www.toutiao.com/video/${item.id}/`,
pubDate: parseDate(item.publish_time, 'X'),
author: item.user?.info.name ?? item.source,
enclosure_url: video?.play_url_list[0],
enclosure_type: video?.play_url_list[0] ? 'video/mp4' : undefined,
user: {
name: item.user?.info.name,
avatar: item.user?.info.avatar_url,
description: item.user?.info.desc,
},
};
}

// text w/o title
case 32: {
const enclosure = item.large_image_list?.pop();
return {
title: item.content?.split('\n')[0],
description: item.rich_content,
link: `https://www.toutiao.com/w/${item.id}/`,
pubDate: parseDate(item.publish_time, 'X'),
author: item.user?.name,
enclosure_url: enclosure?.url,
enclosure_type: enclosure?.url ? `image/${new URL(enclosure.url).pathname.split('.').pop()}` : undefined,
user: {
name: item.user?.name,
avatar: item.user?.avatar_url,
description: item.user?.desc,
},
};
}

// text w/ title
case 60:
default:
return {
title: item.title,
description: item.abstract,
link: `https://www.toutiao.com/article/${item.id}/`,
pubDate: parseDate(item.publish_time, 'X'),
author: item.user_info?.name,
user: {
name: item.user_info?.name,
avatar: item.user_info?.avatar_url,
description: item.user_info?.description,
},
};
}
});

return {
title: `${feed[0].user_info?.name ?? feed[0].user?.name ?? feed[0].source}的头条主页 - 今日头条(www.toutiao.com)`,
description: feed[0].user_info?.description ?? feed[0].user?.desc,
title: `${items[0].user.name}的头条主页 - 今日头条(www.toutiao.com)`,
description: items[0].user.description,
link: `https://www.toutiao.com/c/user/token/${token}/`,
image: feed[0].user_info?.avatar_url ?? feed[0].user?.avatar_url,
image: items[0].user.avatar,
item: items,
};
}

0 comments on commit 2d1c6cc

Please sign in to comment.