SocialSisterYi / bilibili-API-collect

哔哩哔哩-API收集整理【不断更新中....】
https://socialsisteryi.github.io/bilibili-API-collect/
Other
15.3k stars 1.73k forks source link

gRPC playurl 拿不到720p更高质量视频 #1070

Open Arist-B opened 4 months ago

Arist-B commented 4 months ago

提交前请确认

API 来源

IOS 客户端(含粉版、平板版、概念版等)

API 类型

gRPC

API 地址

https://github.com/SocialSisterYi/bilibili-API-collect/tree/cb4f767d4ee3f4f66b6caff04c9c40164ea4af54/grpc_api

详情描述

gRPC playurl api只能拿到最高720p的视频流信息 而且感觉不全 我感觉是没有登陆认证的原因 但是没找到登陆的文档 代码里用了抓包得到的access_key等信息认证 想请问下大家怎么获取更高质量更完整的url信息

这里是我参考/使用的文档:https://github.com/SocialSisterYi/bilibili-API-collect/tree/cb4f767d4ee3f4f66b6caff04c9c40164ea4af54/grpc_api

以下是我的代码:

PlayURLGrpcFetcher::PlayURLGrpcFetcher() {

    /* SSL/TLS configuration */
    grpc::SslCredentialsOptions ssl_opts;
    auto channel_creds = grpc::SslCredentials(ssl_opts);

    /* gRPC服务器地址(:端口) */
    std::string server_addr = "grpc.biliapi.net:443";

    grpc::ChannelArguments channel_args;

    /* 这里与B站 gRPC API Golang 封装使用的参数设置同步 */
    channel_args.SetInt(GRPC_ARG_KEEPALIVE_TIME_MS, 10000);
    channel_args.SetInt(GRPC_ARG_KEEPALIVE_TIMEOUT_MS, 10000);
    channel_args.SetInt(GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS, 1);
    channel_args.SetInt(GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH, 1000000);

    grpc_channel_ = grpc::CreateCustomChannel(server_addr, channel_creds, channel_args);
    if (!grpc_channel_) {
        std::cerr << "Channel creation failed" << std::endl; // 处理错误
    }
    grpc_stub_ = bilibili::app::playurl::v1::PlayURL::NewStub(grpc_channel_);

    /* States of Connectivity: https://grpc.github.io/grpc/core/md_doc_connectivity-semantics-and-api.html */
    grpc_connectivity_state state = grpc_channel_->GetState(true);
    while (state != GRPC_CHANNEL_READY) { // 等待channel建立完成
        grpc_channel_->WaitForStateChange(state, gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_seconds(1, GPR_TIMESPAN)));
        state = grpc_channel_->GetState(true);
    }
}

std::string PlayURLGrpcFetcher::GetPlayURL(int64_t aid, int64_t cid, int64_t qn, int32_t fnver, int32_t fnval, bool fourk, int32_t download, const std::string& access_key, const std::string& sessdata, const std::string& uid) {

    PlayURLReq request;

    /* 视频流URL文档:https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/bangumi/videostream_url.md */
    request.set_aid(aid); // 稿件avid
    request.set_cid(cid); // 视频cid
    request.set_qn(qn); // 视频清晰度标识
    request.set_fnver(fnver); // fnver视频流版本标识; 目前该值恒为0,即fnver=0
    request.set_fnval(fnval); // 视频流格式标识
    request.set_fourk(fourk); // 是否4k
    request.set_download(download); // 下载模式 -> 0:播放 1:flv下载 2:dash下载

    PlayURLReply reply;
    ClientContext context;

    /* 这里的参数如果是hardcode的 那就是通过bmitmproxy抓包获得的 */
    context.AddMetadata("content-type", "application/grpc");
    context.AddMetadata("te", "trailers");
    context.AddMetadata("grpc-encoding", "gzip");
    context.AddMetadata("grpc-timeout", "20100m");
    context.AddMetadata("grpc-accept-encoding", "identity, deflate, gzip");
    context.AddMetadata("user-agent", "bili-universal/80400100 os/ios model/iPhone 13 Pro Max mobi_app/iphone osVer/17.5.1 network/2 grpc-objc-cronet/1.47.0 grpc-c/25.0.0 (ios; cronet_http)");
    context.AddMetadata("x-bili-gaia-vtoken", "");
    // context.AddMetadata("cookie", "SESSDATA=" + sessdata);
    context.AddMetadata("authorization", "identify_v1 " + access_key);
    context.AddMetadata("buvid", "码*******");
    context.AddMetadata("x-bili-metadata-bin", serializeMetadata(access_key));
    context.AddMetadata("x-bill-ticket", "eyJhbGciOi码*******");
    context.AddMetadata("x-bili-fawkes-req-bin", serializeFawkesReq());
    context.AddMetadata("x-bili-restriction-bin", serializeRestriction());
    context.AddMetadata("x-bili-exps-bin", "");
    context.AddMetadata("x-bili-mid", uid); // 用户 UID, 未登录默认为 0. 必需.
    context.AddMetadata("x-bili-device-bin", serializeDevice());
    context.AddMetadata("x-bili-network-bin", serializeNetwork());
    context.AddMetadata("x-bili-locale-bin", serializeLocale());
    context.AddMetadata("x-bili-aurora-eid", generateAuroraEid(std::stoll(uid))); // 如 UFUFQ1AA. 算法见上方函数. 未登录留空. 必需.
    context.AddMetadata("x-bili-aurora-zone", "");
    context.AddMetadata("x-bili-trace-id", generateTraceId()); // 如 06e903399574695df75be114ff63ac64:f75be114ff63ac64:0:0. 算法见上方函数. 必需.

    Status status = grpc_stub_->PlayURL(&context, request, &reply);

    if (status.ok()) {
        if (reply.durl_size() > 0) {
            std::cout << formatPlayURLReply(reply) << std::endl;
            return reply.durl(0).url();
        } else {
            std::cerr << "No URLs in response." << std::endl;
            return "No URLs in response";
        }
    } else {
        std::cerr << "gRPC failed: " << status.error_message() << " (" << status.error_code() << ")" << std::endl;
        return "gRPC failed";
    }
}
SessionHu commented 3 months ago

较新视频的 MP4 格式无高清晰度, 而 DASH 均有, 需要提供完整的请求参数确定实际情况, #606 may help 另外是否尝试过使用 HTTP 接口? 返回结果是否与 gRPC 相同?

cxw620 commented 2 months ago

没发现这种情况,自行检查代码或逻辑错误,不熟悉Cpp。此外也应该提供测试用例。

可以关闭此 Issue。