Vue3 仿抖音项目中的创作者视频数据集:user-elfin16.md 结构与处理链路解析
【免费下载链接】douyinVue3 + Pinia 仿抖音,Vue 在移动端的最佳实践 . Imitate TikTok ,Vue Best practices on Mobile项目地址: https://gitcode.com/GitHub_Trending/do/douyin
导读
在 Vue3 + Pinia 仿抖音项目 的public/data/user_video_list/目录下,存放着一批以.md为扩展名、实为7z 压缩归档(内含 JSON)的视频数据文件。user-elfin16.md正是其中之一:它打包了创作者"彭十六elf"(用户 IDelfin16)的70 条抖音视频作品,涵盖视频元信息、配乐、互动统计、话题标签等完整字段。本文将以该文件为核心,详细拆解其 7z 归档结构与 JSON 数据字段语义,并串联项目从node/采集清洗脚本到src/mock/index.ts前端消费的完整链路,帮助你理解这套"压缩 JSON 当静态接口"的数据工程做法,并掌握如何在本地查看、解析与复现该数据集。
一、文件本质:名为 .md 的 7z 压缩归档
1.1 文件头签名验证
直接使用read_file按 UTF-8 读取该文件会失败,原因在于它根本不是文本文件。用十六进制查看文件头可以确认其真实格式:
37 7a bc af 27 1c 00 04 ... # 即 "7z¼¯'" 的 7z 魔数签名对照 7-Zip 官方规范,37 7A BC AF 27 1C正是 7z 归档文件的魔数(magic bytes)。因此:
- 文件大小约40848 字节,但内部 JSON 解压后约438835 字节,压缩比相当可观;
public/data/user_video_list/下所有user-*.md文件(如user-04074747.md、user-12345xiaolaohu.md、user-71158770.md等)均采用相同格式,并非个别特例。
命名成因推断:结合 node/remove-dist-json.js 会遍历
dist/data删除所有.json文件,以及public/data/下同时存在xxx.md与xxx.json成对文件的现象,可以推断项目方在构建时先将 JSON 打包为 7z 并改用.md扩展名,既压缩了体积又绕过了纯 JSON 的直读,属于一种静态数据伪装技巧。
1.2 本地解压与查看方式
使用 Python 的py7zr可以一行解包:
python3 -c " import py7zr with py7zr.SevenZipFile('public/data/user_video_list/user-elfin16.md', mode='r') as z: print(z.getnames()) # ['user-elfin16.json'] z.extractall(path='/tmp/elfin16_extract') "解包后得到user-elfin16.json,它是一个70 个对象的 JSON 数组,每个对象对应一条视频作品(抖音接口中的aweme)。
二、数据结构:70 条作品记录的字段语义
2.1 顶层字段一览
对解压后的 JSON 进行Object.keys()统计,单条记录共包含21 个顶层字段,与 node/post/process-post.js 中白名单过滤后的字段完全一致:
| 字段 | 含义 |
|---|---|
aweme_id | 视频唯一 ID(如7267478481213181238) |
desc | 作品文案(可含换行与#话题) |
create_time | 发布时间戳(秒) |
music | 配乐信息(见 2.2) |
video | 视频流与封面信息(见 2.3) |
share_url | 站外分享链接 |
statistics | 互动数据(见 2.4) |
status | 作品状态(审核/私密/是否可分享等) |
text_extra | 文案中的话题/链接实体 |
is_top | 是否置顶 |
share_info、duration、image_infos、risk_infos、position、author_user_id、prevent_download、long_video、aweme_control、images、suggest_words | 其余元信息 |
2.2 music:配乐对象
每条视频绑定一个music对象,其字段恰好对应 process-post.js 中的 10 项白名单:
{ "id": 7267478542388760000, "title": "@彭十六elf创作的原声", "author": "彭十六elf", "cover_medium": { "uri": "720x720/...", "url_list": [...], "width": 720, "height": 720 }, "cover_thumb": { "uri": "100x100/...", "url_list": [...], "width": 720, "height": 720 }, "play_url": { "uri": "https://...mp3", "url_list": [...] }, "duration": 25, "user_count": 0, "owner_id": "24058267831", "owner_nickname": "彭十六elf", "is_original": false }数据集内 70 条视频的music.id全部不同(70/70 唯一),即每条作品都使用了独立配乐——包括大量@彭十六elf创作的原声这类原创声源。
2.3 video:视频流与封面
video对象在清洗后保留 7 个字段:play_addr、cover、height、width、ratio、use_static_cover、duration。一个典型样例:
{ "play_addr": { "uri": "v0200fg10000cjdk9q3c77ud1oonqoqg", "url_list": ["https://www.douyin.com/aweme/v1/play/?video_id=...&sign=..."], "width": 1080, "height": 1920, "url_key": "..._h264_1080p_5777261", "data_size": 18662720, "file_hash": "...", "file_cs": "c:0-43596-871e|d:0-9331359-b106,9331360-18662719-d5cf|a:..." }, "cover": { "uri": "tos-cn-i-0813c001/oUd3UMAAIDgHe8AA0ikA2nmC2Q2tCrAbgAkeG9", "url_list": ["W6X9755J4xsbUal6MEmks.png"], "width": 720, "height": 720 }, "height": 3840, "width": 2160, "ratio": "1080p", "use_static_cover": true, "duration": 25843 }值得注意的细节:
- 封面
cover.url_list已经被替换为本地图片文件名(如W6X9755J4xsbUal6MEmks.png),对应public/images/目录中真实存在的同名文件——这正是 node/post/process-post-img.js 做"远程图下载并替换为本地文件名"处理后的结果; video.width/height为 2160×3840,而play_addr分辨率为 1080×1920,两者语义不同(前者是上传源尺寸,后者是播放地址规格);- 全数据集
ratio只出现default、720p、1080p三种取值。
2.4 statistics:互动数据
每条记录包含完整的互动指标,如首条作品:
{ "admire_count": 679, // 赞赏数 "comment_count": 136284, // 评论数 "digg_count": 6400077, // 点赞数 "collect_count": 245585, // 收藏数 "play_count": 0, // 播放数(接口未回填时为 0) "share_count": 446468 // 分享数 }对 70 条记录聚合统计:
- 发布时间跨度:2020-11-02 ~ 2024-03-13(约 3 年 4 个月);
- 累计点赞约5603.9 万、累计评论约70.16 万、累计分享约205.17 万;
- 其中 3 条为置顶作品(
is_top),1 条为图集作品(images非空,文案为"晒出今年的变化吧🎆 #2022年度回忆"),无长视频(long_video为空)。
2.5 text_extra:话题标签
43 条记录带text_extra实体,每个实体含start、end、type、hashtag_name、hashtag_id、is_commerce、caption_start、caption_end等字段,用于在文案中定位并渲染#话题。全数据集话题丰富,涵盖美妆、汽车、节日、生活记录等:#卢浮宫、#马面裙、#国庆、#兰蔻196、#龙年大吉、#街拍、#香港、#阿维塔12、#星纪元es、#ICAR03年轻人的车等,与创作者内容调性吻合。
三、数据链路:从采集清洗到前端消费
3.1 采集与字段白名单清洗
process-post.js 展示了原始接口数据的清洗逻辑:
- 读取
input.json(接口原始响应,含aweme_list); - 对每条
aweme做三层白名单过滤——顶层 21 字段、music10 字段、video8 字段(含horizontal_type、animated_cover,本数据集恰好未用到后两者); - 将清洗结果
concat到按用户保存的 JSON 文件,并同步写ouput.json。
正是这段逻辑保证了user-elfin16.json中每条记录的字段高度统一,也解释了为什么前端代码可以放心按固定 schema 消费。
3.2 图片本地化
process-post-img.js 负责把远程图片替换为本地文件:
- 使用
request发起 HTTP 下载,用nanoid()生成随机文件名存为.png; - 封面
cover.url_list会被替换为单个本地文件名(如W6X9755J4xsbUal6MEmks.png); play_addr.url_list仅保留最后一个播放地址;- 删除
animated_cover等冗余字段。
这就是 2.3 节中封面指向public/images/本地文件的直接来源。同类逻辑也见于 xhs/process-xhs-img.js(小红书数据)、user/process-user-img.js(用户头像)。
3.3 前端 Mock 消费
前端在 src/mock/index.ts 中通过 axios-mock-adapter 拦截请求并拉取这些数据文件:
// 用户主页"作品"列表 mock.onGet(/video\/my/).reply(async (config) => { const r = await _fetch(BASE_URL + '/data/user_video_list/user-12345xiaolaohu.md') const list = await r.json() // ... 将用户信息合并进每条视频 }) // 用户作品列表(按 id 动态加载) mock.onGet(/user\/video_list/).reply(async (config) => { const id = config.params.id const r2 = await _fetch(`${FILE_URL}/user_video_list/user-${id}.md`) const v = await r2.json() if (v) return [200, { data: v, code: 200 }] return [200, { code: 500 }] })其中user-${id}.md的id即路由/组件传入的用户标识(如elfin16),对应文件user-elfin16.md。也就是说:前端fetch一个.md后缀的 URL,response.json()依然能解析出数组,因为服务端返回的其实是压缩前的 JSON 内容(或由构建工具在部署时解压)。结合 node/remove-dist-json.js 删除dist/data下所有.json的逻辑可以推断:部署产物中只保留.md形态的数据文件,进一步坐实了"压缩伪装"的工程意图。
3.4 配套数据:用户资料
与视频数据配套的用户资料存放在 public/data/users.json(13 位用户)与 node/user/data.js。data.js头部的注释清晰列出了字段语义:
/** * signature 签名 * mplatform_followers_count 粉丝数 * total_favorited 获赞 * nickname 昵称 * short_id/unique_id 抖音号,二选一 * country 国家 / province 省 / city 市 * aweme_count 作品数 / favoriting_count 喜欢数 * user.avatar_300x300.url_list[0] 头像 * cover_url[0].url_list[0] 背景cover */src/mock/index.ts 中video/my接口会把users中匹配uid === author_user_id的用户资料合并进每条视频记录,完成"视频 + 作者"的数据组装。
四、如何基于该数据集做二次分析
由于数据是标准 JSON 数组,解压后可直接用脚本做统计分析。例如统计话题分布、按互动量排序等:
python3 -c " import json d = json.load(open('/tmp/elfin16_extract/user-elfin16.json', encoding='utf-8')) # 点赞量 TOP3 for it in sorted(d, key=lambda x: -x['statistics']['digg_count'])[:3]: print(it['statistics']['digg_count'], it['desc'].split(chr(10))[0]) # 话题统计 from collections import Counter tags = Counter(e['hashtag_name'] for it in d for e in it.get('text_extra', [])) print(tags.most_common(5)) "对于需要接入该数据的开发场景,建议遵循以下要点:
- 字段为准:以 process-post.js 的白名单为准,未列出的字段(如
music中的extra、video中的bit_rate等)不会被保留; - 图片已本地化:
cover.url_list指向public/images/下的相对文件名,展示时需拼上/images/前缀;play_addr.url_list仍是抖音 CDN 直链,带签名,存在时效性,离线环境请自行替换为本地视频; play_count可能为 0:接口未回填播放量,前端应做好兜底展示;- 数据只读:仓库为只读演示数据,覆盖 2020-11 至 2024-03 的 70 条作品,适合作为列表渲染、下拉刷新、Mock 接口的教学样例,不宜当作实时业务数据源。
五、小结
user-elfin16.md表面上是 Markdown,本质是 7z 压缩的 JSON 数据集,内含创作者"彭十六elf"的 70 条视频作品记录。它完整串起了本项目"采集清洗(node/post/process-post.js)→ 图片本地化(node/post/process-post-img.js)→ 静态托管(public/data/、public/images/)→ Mock 消费(src/mock/index.ts)"的静态数据流水线,是理解 Vue3 仿抖音项目如何以极低成本模拟真实后端接口的典型样本。无论你是想复刻这套"压缩 JSON 当接口"的方案,还是需要解析抖音aweme数据字段,本文涉及的字段语义与链路代码都值得对照源码继续深挖。
【免费下载链接】douyinVue3 + Pinia 仿抖音,Vue 在移动端的最佳实践 . Imitate TikTok ,Vue Best practices on Mobile项目地址: https://gitcode.com/GitHub_Trending/do/douyin
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考