最近沉迷于在哔哩哔哩看各种国际象棋教学视频,希望能提高自己的棋力。在观看哔哩哔哩up主的视频合集时遇到一个问题,合集里的视频默认是正序播放,不能倒序播放。这让我有点头疼,因为我看的教学视频是搬运过来的,合集中的顺序和时间顺序刚好是相反的。我刚好又有点强迫症,不想在每个视频播放之后手动点击上一集视频播放,所以我就想:有没有什么解决方法。

首先我尝试手动搜索解决办法,在知乎找到了一篇文章,作者写了一个脚本用于哔哩哔哩合集的倒序播放。我如获至宝,马上下载下来试试看。只可惜,没办法用,我不知道是哪里出错了,也许是哪里操作不对,这里就不放这个脚本的链接了。

于是我决定求助AI,我详细描述了我的问题,GPT给出了几种解决方案。前两种方案都是使用别人写的脚本,很可惜的是这两个脚本可能没有及时更新,无法实现倒序播放的功能。所以,还是让GPT给我写一个脚本吧。

GPT先给出了如下的测试版本,并告诉我利用控制台进行调试。我粗略看了一下代码,原理应该是找到哔哩哔哩网站自动播放的原理(这很重要),根据页面的结构写代码,代码也没有很长。为了方便操作,脚本还给页面添加了几个按钮。

// ==UserScript==
// @name         Bilibili Multi-P Reverse Player v1.0
// @namespace    ChatGPT
// @version      1.0
// @description  B站多P视频倒序播放增强
// @author       ChatGPT
// @match        https://www.bilibili.com/video/*
// @run-at       document-end
// @grant        none
// ==/UserScript==

(function () {

    'use strict';


    const STORAGE_KEY = "bili_multi_reverse";


    let reverse =
        localStorage.getItem(STORAGE_KEY) === "1";


    let switched = false;



    function getState(){

        const s = window.__INITIAL_STATE__;

        if(!s || !s.videoData)
            return null;


        return {

            bvid:s.bvid,

            pages:s.videoData.pages,

            current:Number(s.p || 1)

        };

    }



    function jump(page){

        const data=getState();

        if(!data)
            return;


        if(page < 1 ||
           page > data.pages.length)
            return;


        location.href =
            `/video/${data.bvid}?p=${page}`;

    }



    function createUI(){

        if(document.querySelector("#bili-multi-panel"))
            return;


        const box=document.createElement("div");

        box.id="bili-multi-panel";


        box.innerHTML=`

        <button id="bili-prev">
        ◀ 上一P
        </button>

        <button id="bili-next">
        下一P ▶
        </button>

        <button id="bili-reverse">
        </button>

        `;


        box.style.cssText=`

        position:fixed;

        right:25px;

        top:150px;

        z-index:99999;

        display:flex;

        flex-direction:column;

        gap:8px;

        `;


        document.body.appendChild(box);



        const style=`

        #bili-multi-panel button{

            background:#00aeec;

            color:white;

            border:0;

            padding:8px 14px;

            border-radius:6px;

            cursor:pointer;

            font-size:14px;

        }

        `;


        const st=document.createElement("style");

        st.textContent=style;

        document.head.appendChild(st);



        updateButton();



        document
        .querySelector("#bili-prev")
        .onclick=()=>{

            const d=getState();

            if(d)
                jump(d.current-1);

        };



        document
        .querySelector("#bili-next")
        .onclick=()=>{

            const d=getState();

            if(d)
                jump(d.current+1);

        };



        document
        .querySelector("#bili-reverse")
        .onclick=()=>{

            reverse=!reverse;

            localStorage.setItem(
                STORAGE_KEY,
                reverse?"1":"0"
            );

            updateButton();

        };

    }



    function updateButton(){

        const btn=
        document.querySelector("#bili-reverse");

        if(btn){

            btn.innerText =
            reverse
            ?
            "倒序:开启"
            :
            "倒序:关闭";

        }

    }





    function autoPlayReverse(){


        if(!reverse)
            return;


        const data=getState();


        if(!data)
            return;


        if(data.current<=1)
            return;



        const video=
        document.querySelector("video");


        if(!video)
            return;



        video.addEventListener(
            "ended",
            ()=>{

                if(switched)
                    return;


                switched=true;


                jump(data.current-1);


            },
            {
                once:true
            }
        );

    }





    function keyboard(){

        document.addEventListener(
            "keydown",
            e=>{


                if(
                    e.target.tagName==="INPUT" ||
                    e.target.tagName==="TEXTAREA"
                )
                    return;



                const d=getState();

                if(!d)
                    return;



                // [
                if(e.key==="["){

                    jump(d.current-1);

                }


                // ]
                if(e.key==="]"){

                    jump(d.current+1);

                }



                // R

                if(
                    e.key.toLowerCase()==="r"
                ){

                    reverse=!reverse;


                    localStorage.setItem(
                        STORAGE_KEY,
                        reverse?"1":"0"
                    );


                    updateButton();

                }


            }
        );


    }





    function init(){


        createUI();


        keyboard();


        setTimeout(
            autoPlayReverse,
            3000
        );


    }



    setTimeout(
        init,
        3000
    );



})();

把调试结果发给GPT之后,它又给出了第二版代码,这一版代码已经能实现预期的功能了。如果想用这个脚本先要在浏览器里面下载TamperMonkey插件,再把脚本代码输进去。

效果图

写完这个脚本以后才真正感受到AI编程能力之强。JavaScript我几乎不了解,我只是按照GPT给我的提示一步步进行测试,将测试结果返回给它进一步修改代码。这是一个比较简单的任务,但如果要我从头写难度还是比较大的,GPT解决了一切问题。

最后修改:2026 年 07 月 19 日
如果觉得我的文章对你有用,请随意赞赏