first commit

This commit is contained in:
编码猿
2024-09-27 02:06:13 +08:00
commit 852d94fbb9
36760 changed files with 3274413 additions and 0 deletions

View File

@@ -0,0 +1 @@
1205011b-c40e-430e-88b6-45148f1564b6

View File

@@ -0,0 +1 @@
fed59435-cbdb-418f-8e1f-ce7c770a75cd

View File

@@ -0,0 +1,153 @@
var express = require('express');
var router = express.Router();
const config = require("../config");
const GraphqlRequest = require("../http");
var request = require('request');
var fs = require('fs');
router.get('/play', async function(req, res, next) {
let principalId = req.query.principalId;
let photoId = req.query.photoId;
res.json((await GraphqlRequest.post(config.feedById(principalId,photoId))).feedById.currentWork);
});
/**
* 获取视频相关的推荐
* http://127.0.0.1:3000/api/RecommendFeeds?photoId=3xucud23iv78p76
*/
router.get('/RecommendFeeds', async function(req, res, next) {
let photoId = req.query.photoId;
let result = await GraphqlRequest.post(config.RecommendFeeds(photoId))
res.json(result.videoRecommendFeeds);
});
/**
* 获取评论
* http://127.0.0.1:3000/api/CommentList?photoId=3xz5ue2p6betigm
*/
router.get('/CommentList', async function(req, res, next) {
let photoId = req.query.photoId;
let pcursor = req.query.pcursor || "";
res.json((await GraphqlRequest.post(config.shortVideoCommentList(photoId,pcursor))).shortVideoCommentList);
});
/**
* 获取评论展开
* http://127.0.0.1:3000/api/subCommentList?photoId=3xz5ue2p6betigm&rootCommentId=225526137195
*/
router.get('/subCommentList', async function(req, res, next) {
let photoId = req.query.photoId;
let rootCommentId = req.query.rootCommentId;
let pcursor = req.query.pcursor || "";
let ddd = (await GraphqlRequest.post(config.subCommentList(photoId, rootCommentId,pcursor))).subCommentList
res.json(ddd);
});
/**
* 获取收藏的视频
* http://127.0.0.1:3000/api/list
*/
router.get('/list', async function(req, res, next) {
let page = req.query.page || "";
res.json({
data: (await GraphqlRequest.post(config.likedFeeds(page))).likedFeeds
});
});
/**
* 下载视频
*/
router.get('/down', async function(req, res, next) {
let principalId = req.query.principalId;
let pcursors = req.query.pcursor || '';
let count = req.query.count
let result = await GraphqlRequest.post(config.publicFeeds(principalId, pcursors, count))
let { list , pcursor } = result.publicFeeds;
// 创建文件夹
mkDir(principalId)
list.forEach(async (val,index) => {
// 如果遇到 vertical 图片
if (val.workType == 'vertical' || val.workType == 'multiple' || val.workType == 'single') {
DownImage(val)
// val.imgUrls.forEach((vas,ix) => {
// DownImage(vas,vas.match(/atlas\/([\s\S]*?).webp/)[1],val.user.id)
// })
} else{
let VideoUrl = await GraphqlRequest.post(config.feedById(val.user.id, val.id))
console.log(`---------------------- ${index+1}: 请求视频: ${val.id} 的下载地址 : `, VideoUrl);
DownMp4(VideoUrl.feedById.currentWork.playUrl, val.id, val.user.id)
}
});
res.json({
data: result.publicFeeds
});
});
/**
*
* @param {*} url 视频下载地址
* @param {*} id 视频文件名
* @param {*} page 用主播id作为文件夹名称
*/
function DownMp4(url, id, page) {
var options = {
url: url,
headers: {
'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36'
}
};
//发送get请求下载视频
request(options)
.on('error', function(err) {
console.log(err)
})
// 将视频写入到mp4文件夹里
.pipe(fs.createWriteStream(`mp4/${page}/${id}.mp4`))
}
function DownImage(data) {
let promise = Promise.resolve();
data.imgUrls.forEach((val,ix) => {
console.log("图片地址 ------------- ", val)
promise = promise.then(() => {
return new Promise(resolve => {
setTimeout(async () => {
var options = {
url: val,
headers: { 'Upgrade-Insecure-Requests': '1','User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36'}
};
//发送get请求下载视频
request(options)
.on('error', function(err) {
console.log(err)
})
// 将视频写入到mp4文件夹里
.pipe(fs.createWriteStream(`mp4/${data.user.id}/${val.match(/atlas\/([\s\S]*?).webp/)[1]}.webp`))
resolve('成功');
},1)
}).then(val => {
console.log("Promise val: ", val);
})
})
})
}
/**
* 创建文件夹
* @param {*} page
*/
function mkDir(page){
fs.mkdir(`mp4/${page}`, 0777, err => err ? console.log(err) : console.log('文件夹创建成功'))
}
module.exports = router;

View File

@@ -0,0 +1,57 @@
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var lessMiddleware = require('less-middleware');
var logger = require('morgan');
var indexRouter = require('./routes/index');
var playApi = require('./api/play');
var app = express();
app.use((req, res, next) => {
res.header("Access-Control-Allow-Credentials",true);
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET, PUT, POST, OPTIONS') ;
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With')
if (req.method == 'OPTIONS') {
res.sendStatus(200)
} else {
next()
}
});
// page engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('page engine', 'pug');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(lessMiddleware(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/api', playApi);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;

View File

@@ -0,0 +1 @@
22697183-260f-43f1-8160-5c9b57e80256

View File

@@ -0,0 +1,87 @@
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('kuaishou:server');
var http = require('http');
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address();
console.log(`App is Run: http://127.0.0.1:3000`)
}

View File

@@ -0,0 +1 @@
e0b40b91-f843-43c3-8cd3-0786b6f8a029

View File

@@ -0,0 +1,101 @@
module.exports = {
url: 'https://live.kuaishou.com/m_graphql',
subCommentList: (photoId,rootCommentId,pcursor = "") => {
return `
{
subCommentList(photoId: "${photoId}", rootCommentId: "${rootCommentId}", pcursor: "${pcursor}", count: 20) {
pcursor
subCommentsList {
commentId,authorId,authorName,content
headurl,timestamp,authorEid,status,replyToUserName,replyTo,
replyToEid
}
}
}`
},
RecommendFeeds: (photoId) => {
return `
{
videoRecommendFeeds(photoId: "${photoId}", count: 40) {
list {
user {
id,avatar,name
},
id,thumbnailUrl,poster,workType,type,useVideoPlayer,imgUrls,
imgSizes,magicFace,musicName,caption,location,liked,onlyFollowerCanComment,
relativeHeight,timestamp,width,height,
counts {
displayView,displayLike,displayComment
},
expTag
}
}
}
`
},
shortVideoCommentList: (photoId, pcursor = "") => {
return `{
shortVideoCommentList(photoId: "${photoId}", page: 1, pcursor: "${pcursor}", count: 100) {
commentCount,realCommentCount,pcursor,
commentList {
commentId,authorId,authorName,content,headurl,timestamp,authorEid,status,
subCommentCount,subCommentsPcursor,likedCount,liked,
subComments {
commentId,authorId,authorName,content,headurl,timestamp,authorEid
status,replyToUserName,replyTo,replyToEid
}
}
}
}`
},
// 喜欢页面 请求参数
likedFeeds: (pcursor = "") => {
return `{
likedFeeds(principalId: "geekhelp", pcursor: "${pcursor}", count: 42) {
pcursor
list {
id,thumbnailUrl,poster,workType,type,useVideoPlayer,imgUrls,imgSizes,magicFace,
musicName,caption,location,liked,onlyFollowerCanComment,relativeHeight,timestamp,width,height,
counts {
displayView,displayLike,displayComment
},
user {
id,eid,name,avatar,
},
expTag
}
}
}`;
},
// 视频真实播放地址 请求参数
feedById: (principalId, photoId)=> {
return `{
feedById(principalId: "${principalId}", photoId: "${photoId}") {
currentWork {
playUrl,poster,caption
}
}
}`;
},
publicFeeds: (principalId, pcursor = "", count = 24) => {
return `{
publicFeeds(principalId: "${principalId}", pcursor: "${pcursor}", count: ${count}) {
pcursor,
list {
id,thumbnailUrl,poster,workType,type,useVideoPlayer,imgUrls,imgSizes,magicFace,musicName,
caption,location,liked,onlyFollowerCanComment,relativeHeight,timestamp,width,height,
counts {
displayView,displayLike,displayComment
},
user {
id,eid,name,avatar,cityName
},
expTag
}
}
}`
}
};

View File

@@ -0,0 +1 @@
6df630bf-2d19-4307-8393-baa1797ac117

View File

@@ -0,0 +1,17 @@
const { GraphQLClient } = require("graphql-request");
const config = require("../config/index");
class GraphqlRequest {
constructor() {
this.client = new GraphQLClient(config.url, {
headers: {
Cookie: 'did=web_585efba7a42ad13f737dc3c8f58209f1; didv=1594914486460; clientid=3; client_key=65890b29; Hm_lvt_86a27b7db2c5c0ae37fee4a8a35033ee=1596097714; userId=58344290; kuaishou.live.bfb1s=3e261140b0cf7444a0ba411c6f227d88; userId=58344290; kuaishou.live.web_st=ChRrdWFpc2hvdS5saXZlLndlYi5zdBKgAbKc6XmzE6FdiBdCzoaCcECzx_U2-TCOKF0lju8_OumrrmmDqR9uNPQZcBk0MS02hW6hPW-xbUIHIkNZiPJUvL7Ei-0-0XH4ttc5cfpYcVA-tqFmQRL3D8zHn8PRN1mHHfbgtU6J-hGQ2c6J8N4uOf2ryJ0IhSiBIfpKdIhZMc2MaCY4126pPjiKNkOtHuvWHx0UNgKQDyCCoGBZjeZBhuQaEvsuz1ia_EwztqTXeP7HMv4rLSIgpOyeF5ljcpqiYhyVG9E1CCMgjL4Vi47bIpVT4Xero3EoBTAB; kuaishou.live.web_ph=00cee9c348525cb118a6e2475de40e5c66d8',
},
})
}
async post(query) {
return await this.client.request(query)
}
}
module.exports = new GraphqlRequest();

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,20 @@
{
"name": "kuaishou",
"version": "0.0.0",
"private": true,
"scripts": {
"dev": "node-dev ./bin/www"
},
"dependencies": {
"axios": "^0.19.2",
"cookie-parser": "~1.4.4",
"debug": "~2.6.9",
"express": "^4.16.4",
"graphql-request": "^1.8.2",
"http-errors": "~1.6.3",
"less-middleware": "~2.2.1",
"morgan": "~1.9.1",
"pug": "^2.0.4",
"request": "^2.88.2"
}
}

View File

@@ -0,0 +1 @@
05d24c42-200a-40ee-b165-3ee1913d144b

View File

@@ -0,0 +1 @@
a5002f32-53e0-4591-9f76-e5ea7fc89a8a

View File

@@ -0,0 +1 @@
176fe3ac-5a58-4fd2-bdbe-a15f9d8c8577

View File

@@ -0,0 +1,127 @@
let pageNum = "";
getVideoList();
/**
* 发送ajax请求数据
*/
function getVideoList() {
Http("/list", { page: pageNum }, res=> {
let MMList = res.data;
pageNum = MMList.pcursor;
MMList.list.forEach(function (val,index) {
RenderList(val);
})
})
}
function RenderList(val) {
$("ul").append(`
<li class="list">
<div class="back">
<div class="zz" style="background: url('${val.thumbnailUrl}'); background-position: center center;"></div>
<img src="${val.thumbnailUrl}"/>
</div>
<div class="list-bottom">
<div class="bottom-info">
<a target="_blank" title="${val.user.id}" href="https://live.kuaishou.com/profile/${val.user.id}">
<img class="avatar" src="${val.user.avatar}"/>
<span class="title">${val.caption}</span>
</a>
</div>
<div class="action" principalId="${val.user.id}" photoId="${val.id}">
<a class="down">下载</a>
<a class="play">播放</a>
</div>
</div>
</li>
`);
BindPlayClick();
BindDownClick();
}
// 播放视频
function BindPlayClick() {
document.querySelectorAll(".play").forEach((val,index) =>{
val.onclick= function () {
Http('/play',{
principalId: $(val).parent().attr("principalId"),
photoId: $(val).parent().attr("photoId")
},url=> {
$(".video video").attr("src", url.playUrl);
$(".video").slideDown("slow");
})
}
})
}
// 下载视频
function BindDownClick() {
document.querySelectorAll(".down").forEach((val,index) =>{
val.onclick= function () {
Http('/play',{
principalId: $(val).parent().attr("principalId"),
photoId: $(val).parent().attr("photoId")
},url=> {
downMp4( url.playUrl, $(val).parent().attr("photoId"))
})
}
});
}
// 滚动加载数据
$(window).scroll(function () {
var scrollTop = $(this).scrollTop();
var scrollHeight = $(document).height();
var windowHeight = $(this).height();
if (scrollTop + windowHeight == scrollHeight) {
getVideoList()
console.log("到底了,发起请求")
}
});
// 关闭视频播放弹窗
$(".close").click(function () {
$("video").get(0).pause();
$(".video video").attr("src", "");
$(".video").slideUp("slow");
});
// video 父元素被悬浮就开始视频播放
// 以实现不静音而自动播放
$(".video").mouseover(function () {
$("video").get(0).play()
});
// 发送ajax请求
function Http(URL, params,callback) {
$.ajax({
url: `http://127.0.0.1:3000/api${URL}`,
type: 'GET',
data: params,
success: (res)=> {
callback(res)
}
})
}
// 下载MP4视频
function downMp4(urls, photoId) {
fetch(urls).then(res => res.blob()).then(blob => {
const a = document.createElement('a');
document.body.appendChild(a);
a.style.display = 'none';
const url = window.URL.createObjectURL(blob);
a.href = url;
a.download = `bmy-${photoId}.mp4`;
a.click();
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
});
}

View File

@@ -0,0 +1 @@
0a439c7f-73ce-45b1-a330-6586fe91ebfa

View File

@@ -0,0 +1 @@
ul{display:flex;overflow:hidden;justify-content:space-around;flex-wrap:wrap}.video{text-align:center;background:rgba(0,0,0,0.87843137);width:100%;height:100%;position:fixed;z-index:9;display:none}.video .close{width:60px;height:60px;background:rgba(255,255,255,0.61176471);border-radius:100%;color:#615e5e;text-align:center;line-height:55px;position:absolute;right:20px;top:30px;font-size:31px;cursor:pointer}.list{width:15%;height:260px;margin:10px 10px 10px 10px;background:#fff}.list .back{width:100%;height:178px;text-align:center;position:relative;overflow:hidden}.list .back .zz{position:absolute;width:100%;height:100%;z-index:2;background:#000;filter:blur(10px)}.list .back img{width:103px;height:178px;position:absolute;z-index:3;left:50%;margin-left:-51.5px}.list .list-bottom{padding:10px 5px 5px 5px;box-sizing:border-box}.list .list-bottom .action{display:flex;justify-content:space-between;height:36px;align-items:center;padding:3px 5px 0 5px;color:#b7b7b7;font-size:13px}.list .list-bottom .action a{cursor:pointer}.list .list-bottom .bottom-info a{display:flex;justify-content:flex-start;align-items:center;color:#bababa}.list .list-bottom .bottom-info a .avatar{width:35px;height:35px;border-radius:100%}.list .list-bottom .bottom-info a .title{font-size:13px;width:230px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;margin-left:10px}

View File

@@ -0,0 +1,97 @@
ul {
display: flex;
overflow: hidden;
justify-content: space-around;
flex-wrap: wrap;
}
.video {
text-align: center;
background: rgba(0, 0, 0, 0.8784313725490196);
width: 100%;
height: 100%;
position: fixed;
z-index: 9;
display: none;
.close {
width: 60px;
height: 60px;
background: rgba(255, 255, 255, 0.611764705882353);
border-radius: 100%;
color: #615e5e;
text-align: center;
line-height: 55px;
position: absolute;
right: 20px;
top: 30px;
font-size: 31px;
cursor: pointer;
}
}
.list {
width: 15%;
height: 260px;
margin: 10px 10px 10px 10px;
background: #fff;
.back {
width: 100%;
height: 178px;
text-align: center;
position: relative;
overflow: hidden;
.zz {
position: absolute;
width: 100%;
height: 100%;
z-index: 2;
background: #000;
filter: blur(10px);
}
img {
width: 103px;
height: 178px;
position: absolute;
z-index: 3;
left: 50%;
margin-left: -103px / 2;
}
}
.list-bottom {
padding: 10px 5px 5px 5px;
box-sizing: border-box;
.action {
display: flex;
justify-content: space-between;
height: 36px;
align-items: center;
padding: 3px 5px 0 5px;
color: #b7b7b7;
font-size: 13px;
a {
cursor: pointer;
}
}
.bottom-info {
a {
display: flex;
justify-content: flex-start;
align-items: center;
color: #bababa;
.avatar {
width: 35px;
height: 35px;
border-radius: 100%;
}
.title {
font-size: 13px;
width: 230px;
overflow: hidden;
white-space: nowrap;
text-overflow:ellipsis;
margin-left: 10px;
}
}
}
}
}

View File

@@ -0,0 +1 @@
body,ul,li,p,a{margin:0;padding:0;list-style:none;text-decoration:none}body{background:#f5f5f5}body,html{width:100%;height:100%}video{outline:none}

View File

@@ -0,0 +1,18 @@
body, ul,li,p,a{
margin: 0;
padding: 0;
list-style: none;
text-decoration: none;
}
body {
background: #f5f5f5;
}
body,html {
width: 100%;
height: 100%;
}
video {
outline: none;
}

View File

@@ -0,0 +1 @@
20545287-a928-4285-8880-d6ef4af75ab7

View File

@@ -0,0 +1,11 @@
var express = require('express');
var router = express.Router();
const config = require("../config");
const GraphqlRequest = require("../http");
router.get('/', async (req, res, next) => {
let page = req.query.page || "";
res.render('index');
});
module.exports = router;

View File

@@ -0,0 +1 @@
96f6d931-cb08-4924-9dcc-eb189c63f9bb

View File

@@ -0,0 +1,6 @@
extends layout
block content
h1= message
h2= error.status
pre #{error.stack}

View File

@@ -0,0 +1,13 @@
extends layout
block css
link(rel='stylesheet', href='/stylesheets/index.less')
block content
.video
.close x
video(src="", loop, controls, height="100%")
ul
block js
script(src="/javascripts/index.less")

View File

@@ -0,0 +1,11 @@
doctype html
html
head
title= title
link(rel='stylesheet', href='/stylesheets/style.css')
script(src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js")
block css
body
block content
block js

View File

@@ -0,0 +1,171 @@
快手接口整理
接口地址https://live.kuaishou.com/m_graphql
注意:
1下面接口调用时请先在PC端登录快手然后复制请求头中的cookies然后使用后端伪造请求头来调用快手接口后端拿到数据后
将数据返回给我们自己的前端。
2项目中只有这一个接口地址通过调用接口中不同方法来获取不同数据
3后端需要使用专门的 graphql 插件去发送请求
1用户主页喜欢视频列表接口
请求POST
调用方法likedFeedsQuery()
方法参数:
1principalId 用户快手id用户自定义的用户名
2pcursor 当前的页码类似分页的page参数如果留空默认第一页
3count 一页展示多少条数据类似分页的limit参数默认24
调用实例:
query {
likedFeeds(principalId: "geekhelp", pcursor: "1.582321864999E12", count: 24) {
pcursor
list {
id,thumbnailUrl,poster,workType,type,useVideoPlayer,imgUrls,imgSizes,magicFace,
musicName,caption,location,liked,onlyFollowerCanComment,relativeHeight,timestamp,width,height,
counts {
displayView,displayLike,displayComment
},
user {
id,eid,name,avatar,
},
expTag
}
}
}
2获取视频的评论
请求POST
调用方法commentListQuery()
方法参数:
1count 评论数
2page 无用参数但是必填默认1即可
3pcursor 分页的页面,每次请求都会返回下次页码
4photoId 要获取视频评论的id
query {
shortVideoCommentList(photoId: '', page: 1, pcursor: '', count: 20t) {
commentCount,realCommentCount,pcursor,
commentList {
commentId,authorId,authorName,content,headurl,timestamp,authorEid,status,
subCommentCount,subCommentsPcursor,likedCount,liked,
subComments {
commentId,authorId,authorName,content,headurl,timestamp,authorEid
status,replyToUserName,replyTo,replyToEid
}
}
}
}
3获取热门推荐视频
请求POST
调用方法videoRecommendFeeds()
方法参数:
1count 展示多少条
2photoId 视频的id参数
调用实例:
query {
videoRecommendFeeds(photoId: $photoId, count: $count) {
list {
user {
id,avatar,name
},
id,thumbnailUrl,poster,workType,type,useVideoPlayer,imgUrls,
imgSizes,magicFace,musicName,caption,location,liked,onlyFollowerCanComment,
relativeHeight,timestamp,width,height,
counts {
displayView,displayLike,displayComment
},
expTag
}
}
}
4获取视频的真实MP4播放地址
请求POST
调用方法feedById()
方法参数:
1principalId 主播的快手id从 likedFeeds 方法 list.user.id 获得
2photoId 视频的id参数从 likedFeeds 方法 list.id 中获得
调用实例:
query {
feedById(principalId: "xxx", photoId: "xxxx") {
currentWork {
playUrl,poster
}
}
}
5获取主播首页的视频
请求POST
调用方法publicFeeds()
方法参数:
1principalId 主播的快手id
2pcursor 分页页码
3count 一页展示多少数据
调用实例:
query {
publicFeeds(principalId: "xxxx", pcursor: "xxxx", count: 24) {
pcursor,
list {
id,thumbnailUrl,poster,workType,type,useVideoPlayer,imgUrls,imgSizes,magicFace,musicName,
caption,location,liked,onlyFollowerCanComment,relativeHeight,timestamp,width,height,
counts {
displayView,displayLike,displayComment
},
user {
id,eid,name,avatar,cityName
},
expTag
}
}
}
6获取视频回复的展开更多
请求POST
调用方法subCommentList()
方法参数:
1photoId 视频id
2rootCommentId 回复的顶级评论
3pcursor 下标
4count 数量
调用实例:
query {
subCommentList(photoId: $photoId, rootCommentId: $rootCommentId, pcursor: $pcursor, count: $count) {
pcursor
subCommentsList {
commentId,authorId,authorName,content
headurl,timestamp,authorEid,status,replyToUserName,replyTo,
replyToEid
}
}
}
7对视频进行 喜欢收藏
请求POST
调用方法likeVideo()
方法参数:
1photoId 视频id
2principalId 快手用户id
3cancel 0 喜欢1 取消喜欢
query {
likeVideo(photoId: $photoId, principalId: $principalId, cancel: $cancel) {
result
}
}
7获取自己关注的主播有哪些正在进行直播
请求GET
https://live.kuaishou.com/rest/wd/live/liveStream/myfollow