吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 273|回复: 7
收起左侧

[经验求助] AI写的抖音跳过长视频Autox-v7.2.1脚本,如何提高时长识别准确率?

[复制链接]
lupaf 发表于 2026-5-6 16:33
266吾爱币
在推荐页和个人主页刷视频,不想看长视频,所以让豆包写了个Autox.JS脚本,但是背景负责的时长识别错误率高{:1_904:},有没有更准确的方法,我是小白,希望大神  修改后附上全部代码(网盘下载也行),谢谢了

"ui";
var config = storages.create("douyin_home_skip");
var isPause = true;
var running = true;

// 重置全局状态
function resetState() {
isPause = true;
}

function qdui() {
ui.layout(
<ScrollView>
<vertical>
<appbar>
<horizontal>
<toolbar id="bt" title="抖音长视频跳过" gravity="center" textColor="red" layout_weight="1" />
<Switch id="autoService" text="无障碍" checked="{{auto.service != null}}" padding="20 20 8 8" textSize="15sp" layout_gravity="right" />
</horizontal>
</appbar>

            <text text="主页完整观看设置:" textSize="16sp" textColor="red" margin="10"/>
            <horizontal padding="5">
                <checkbox id="homeOverTime" text="超过 秒 上滑(长视频跳过)" checked="true" />
                <input id="homeOverTimeVal" hint="120" w="80" gravity="center" inputType="number" />
                <text text="秒" />
            </horizontal>

            <text text="温馨提示:" gravity="left" textColor="red" margin="10 5"/>
            <text text="1. 仅底部30%区域识别时长" gravity="left" margin="2"/>
            <text text="2. 长视频(>设定值)立即跳过" gravity="left" margin="2"/>
            <text text="3. 短视频完整播放" gravity="left" margin="2"/>
            <text text="4. 图文内容无进度条直接上滑" gravity="left" margin="2"/>
            <text text="5. 悬浮窗:上暂停/开始,下停止" gravity="left" margin="2"/>

            <button id="start" text="开始运行" style="Widget.AppCompat.Button.Colored" margin="15"/>
        </vertical>
    </ScrollView>
);

ui.autoService.on("check", function (checked) {
    if (checked && auto.service == null) {
        app.startActivity({ action: "android.settings.ACCESSIBILITY_SETTINGS" });
    }
    if (!checked && auto.service != null) {
        auto.service.disableSelf();
    }
});

readconfig();

ui.homeOverTimeVal.setVisibility(ui.homeOverTime.checked ? 0 : 8);

ui.homeOverTime.on("check", function (checked) {
    ui.homeOverTimeVal.setVisibility(checked ? 0 : 8);
});

ui.emitter.on("resume", function () {
    ui.autoService.checked = auto.service != null;
});

ui.start.on("click", function () {
    if (auto.service == null) {
        toast("请先开启无障碍服务!");
        return;
    }
    if (!ui.homeOverTime.checked) {
        toast("请勾选「超过秒上滑」模式");
        return;
    }
    saveconfig();
    resetState();
    createFloatWindow();
    runDouyinSkip();
});

}

// ==============================================
// 只修改这里:修复暂停按钮没反应,其他全保留原版
// ==============================================
var window;
function createFloatWindow() {
try {
window = floaty.window(
<vertical bg="#88000000" padding="5">
<button id="pauseBtn" text="▶" width="50" height="40" color="#FFFFFF" />
<button id="stopBtn" text="■" width="50" height="40" color="#FFFFFF" />
</vertical>
);
window.setPosition(10, device.height / 3);

    setInterval(function(){}, 1000);

    // 修复:暂停点击立即生效、重置状态
    window.pauseBtn.click(function(){
        isPause = !isPause;
        if(isPause){
            window.pauseBtn.setText("▶");
            toast("已暂停");
        }else{
            window.pauseBtn.setText("⏸");
            toast("已恢复运行");
        }
    });

    window.stopBtn.click(function(){
        toast("脚本已停止");
        running = false;
        resetState();
        exit();
    });
} catch (e) {
    toast("请开启悬浮窗权限");
}

}

function parseTotalDuration(text) {
if (!text) return null;
var match = text.match(/\/\s(\d+):(\d+)/);
if (match) {
var m = parseInt(match[1]);
var s = parseInt(match[2]);
if (!isNaN(m) && !isNaN(s) && s < 60) {
return m
60 + s;
}
}
match = text.match(/^(\d+):(\d+)$/);
if (match) {
var m = parseInt(match[1]);
var s = parseInt(match[2]);
if (!isNaN(m) && !isNaN(s) && s < 60) {
return m * 60 + s;
}
}
return null;
}

function hasSeekBar() {
try {
return className("android.widget.SeekBar").findOne(500) != null;
} catch(e) {
return false;
}
}

// 只在屏幕底部 30% 区域查找
function scanForDuration(durationMs) {
let screenH = device.height;
let areaTop = screenH * 0.7;
let areaBottom = screenH;

var start = new Date().getTime();
while (new Date().getTime() - start < durationMs) {
    if(isPause) return null;

    var items = className("android.widget.TextView").find();
    for (var i = 0; i < items.length; i++) {
        let item = items[i];
        let bounds = item.bounds();
        if(bounds.centerY() >= areaTop && bounds.centerY() <= areaBottom){
            var t = item.text();
            if (t) {
                var sec = parseTotalDuration(t);
                if (sec && sec > 0) {
                    log("底部区域识别时长:" + sec + "秒");
                    return sec;
                }
            }
        }
    }
    sleep(40);
}
return null;

}

function getVideoDuration() {
try {
if (isPause) return null;
if (!hasSeekBar()) return null;

    var bar = className("android.widget.SeekBar").findOne(1500);
    if (!bar) return null;

    var b = bar.bounds();
    var cx = b.centerX();
    var cy = b.centerY();
    var lx = b.left + 40;

    var res = null;
    // 扫描时长:2300ms
    var th = threads.start(() => {
        res = scanForDuration(2300);
    });

    // 按压时长:2100ms
    if(!isPause){
        gesture(2100, [cx, cy], [lx, cy]);
    }

    th.join();
    return res;
} catch (e) {
    log("获取时长异常:" + e);
    return null;
}

}

function getVideoDurationWithRetry() {
log("开始识别视频时长...");
var t = getVideoDuration();
if (t) return t;

sleep(800);
log("重试识别...");
return getVideoDuration();

}

function runDouyinSkip() {
threads.start(function () {
console.show();
isPause = false;
app.launchApp("抖音");
sleep(4000);
skipLoop();
});
}

function skipLoop() {
var count = 0;
while (running) {
if (isPause) {
sleep(300);
continue;
}

    count++;
    var limit = parseInt(ui.homeOverTimeVal.text()) || 120;
    log("\n======= 第" + count + "个视频 =======");

    // 进入新视频随机等待 500~1000ms
    sleep(random(500, 1000));

    if (!hasSeekBar()) {
        log("图文内容,直接上滑");
        swipeUp();
        continue;
    }

    var sec = getVideoDurationWithRetry();

    if (sec && sec > 0) {
        log("视频时长:" + sec + "秒 / 限制:" + limit + "秒");
        if (sec > limit) {
            log("长视频,立即跳过");
            swipeUp();
        } else {
            var play = sec + 1;
            log("短视频,播放 " + play + " 秒");
            sleep(play * 1000);
            log("播放完毕,上滑");
            swipeUp();
        }
    } else {
        log("识别失败,10秒后跳过");
        sleep(10000);
        swipeUp();
    }
}

}

// 随机滑动坐标 + 随机手势时长
function swipeUp() {
if(isPause) return;
var baseX = device.width / 2;
var randomX = baseX + random(-10, 10);
var startY = device.height 0.75 + random(-10, 10);
var endY = device.height
0.25 + random(-10, 10);
var duration = random(300, 500);
swipe(randomX, startY, randomX, endY, duration);
sleep(700);
}

function saveconfig() {
config.put("homeOverTime", ui.homeOverTime.checked);
config.put("homeOverTimeVal", ui.homeOverTimeVal.text());
}

function readconfig() {
ui.homeOverTime.checked = config.get("homeOverTime", true);
ui.homeOverTimeVal.setText(config.get("homeOverTimeVal", "120"));
}

qdui();

最佳答案

查看完整内容

/** * 抖音长视频跳过脚本 - 精简版 * * 特点:无UI界面,直接运行 * 悬浮窗控制:点击暂停/继续,长按停止 */ var config = storages.create("douyin_home_skip_lite"); var isPause = false; var running = true; var floatWindow = null; // ============================================================ // 配置参数(默认值,可从storage读取) // ================================================ ...

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

xxggla666 发表于 2026-5-6 16:33
/**
* 抖音长视频跳过脚本 - 精简版
*
* 特点:无UI界面,直接运行
* 悬浮窗控制:点击暂停/继续,长按停止
*/

var config = storages.create("douyin_home_skip_lite");
var isPause = false;
var running = true;
var floatWindow = null;

// ============================================================
// 配置参数(默认值,可从storage读取)
// ============================================================
var LIMIT = config.get("limit", 120);          // 长视频阈值(秒)
var SCAN_RATIO = config.get("scanRatio", 0.5); // 扫描区域比例
var GESTURE_DURATION = config.get("gestureDuration", 3000); // 手势按压时间(ms)
var RETRY_COUNT = config.get("retryCount", 2);  // 重试次数

// 保存配置
config.put("limit", LIMIT);
config.put("scanRatio", SCAN_RATIO);
config.put("gestureDuration", GESTURE_DURATION);
config.put("retryCount", RETRY_COUNT);

console.show();
console.log("抖音长视频跳过脚本 精简版");
console.log("限制=" + LIMIT + "秒,扫描比例=" + SCAN_RATIO);
console.log("手势=" + GESTURE_DURATION + "ms,重试=" + RETRY_COUNT + "次");
console.log("控制:悬浮窗点击=暂停/继续,长按1.5秒=停止");

// ============================================================
// 悬浮窗 - 官方示例实现
// ============================================================
function createFloatWindow() {
    floatWindow = floaty.window(
        <frame>
            <button id="action" text="暂停" w="90" h="40" bg="#77ffffff"/>
        </frame>
    );
   
    // 设置初始位置
    floatWindow.setPosition(10, device.height / 3);
   
    // 保持脚本存活
    setInterval(function () {}, 1000);
   
    // 触摸处理
    var x = 0, y = 0;
    var windowX, windowY;
    var downTime;
   
    floatWindow.action.setOnTouchListener(function(view, event) {
        switch (event.getAction()) {
            case event.ACTION_DOWN:
                x = event.getRawX();
                y = event.getRawY();
                windowX = floatWindow.getX();
                windowY = floatWindow.getY();
                downTime = new Date().getTime();
                return true;
            case event.ACTION_MOVE:
                floatWindow.setPosition(windowX + (event.getRawX() - x),
                    windowY + (event.getRawY() - y));
                if (new Date().getTime() - downTime > 1500) {
                    toast("停止脚本");
                    running = false;
                    exit();
                }
                return true;
            case event.ACTION_UP:
                if (Math.abs(event.getRawY() - y) < 5 && Math.abs(event.getRawX() - x) < 5) {
                    isPause = !isPause;
                    floatWindow.action.setText(isPause ? "继续" : "暂停");
                    toast(isPause ? "已暂停" : "已继续");
                }
                return true;
        }
        return true;
    });
}

// ============================================================
// 主程序
// ============================================================
threads.start(function() {
    // 创建悬浮窗
    createFloatWindow();
    console.log("悬浮窗创建成功");
   
    // 检查无障碍服务
    if (auto.service == null) {
        console.log("请先开启无障碍服务!");
        toast("请先开启无障碍服务!");
        sleep(2000);
        app.startActivity({ action: "android.settings.ACCESSIBILITY_SETTINGS" });
        return;
    }
   
    // 检查悬浮窗权限
    if (!floaty.checkPermission()) {
        console.log("请开启悬浮窗权限!");
        toast("请开启悬浮窗权限!");
        sleep(2000);
        floaty.requestPermission();
        return;
    }
   
    console.log("启动抖音...");
    app.launchApp("抖音");
    sleep(4000);
   
    console.log("开始执行长视频跳过...");
    mainLoop();
});

// ============================================================
// 时长识别函数
// ============================================================
function enhancedParseDuration(text) {
    if (!text) return null;
    var patterns = [
        /\/\s*(\d+):(\d+)/,
        /(\d+):(\d+)$/,
        /(\d+)\s*分\s*(\d+)\s*秒/,
        /(\d+)\s*:\s*(\d+)/,
        /(\d+)\s*min\s*(\d+)\s*s/i,
        /(\d+)\s*:\s*(\d+)\s*\//
    ];
    for (var i = 0; i < patterns.length; i++) {
        var match = text.match(patterns[i]);
        if (match) {
            var m = parseInt(match[1]);
            var s = parseInt(match[2]);
            if (!isNaN(m) && !isNaN(s) && s < 60 && m < 60) {
                return m * 60 + s;
            }
        }
    }
    return null;
}

function hasSeekBar() {
    try {
        return className("android.widget.SeekBar").findOne(500) != null;
    } catch (e) {
        return false;
    }
}

function getDurationFromSeekBar() {
    try {
        var seekBar = className("android.widget.SeekBar").findOne(1500);
        if (!seekBar) return null;
        var barBounds = seekBar.bounds();
        var barBottom = barBounds.bottom;
        var textViews = className("android.widget.TextView").find();
        for (var i = 0; i < textViews.length; i++) {
            var tv = textViews[i];
            var tvBounds = tv.bounds();
            if (tvBounds.top >= barBottom && tvBounds.top <= barBottom + 250) {
                var text = tv.text();
                if (text) {
                    var sec = enhancedParseDuration(text);
                    if (sec && sec > 0) {
                        return sec;
                    }
                }
            }
        }
        return null;
    } catch (e) {
        return null;
    }
}

function scanForDuration(durationMs) {
    var ratio = SCAN_RATIO;
    var screenH = device.height;
    var areaTop = screenH * (1 - ratio);
    var areaBottom = screenH * 0.95;
    var bestResult = null;
    var start = new Date().getTime();
    while (new Date().getTime() - start < durationMs) {
        if (isPause || !running) return null;
        var items = className("android.widget.TextView").find();
        for (var i = 0; i < items.length; i++) {
            var bounds = items[i].bounds();
            if (bounds.centerY() >= areaTop && bounds.centerY() <= areaBottom) {
                var t = items[i].text();
                if (t) {
                    var sec = enhancedParseDuration(t);
                    if (sec && sec > 0) {
                        bestResult = sec;
                    }
                }
            }
        }
        sleep(100);
    }
    return bestResult;
}

function getVideoDuration() {
    try {
        if (isPause || !running) return null;
        if (!hasSeekBar()) return null;

        var bar = className("android.widget.SeekBar").findOne(1500);
        if (!bar) return null;

        var b = bar.bounds();
        var cx = b.centerX();
        var cy = b.centerY();
        var lx = b.left + 40;

        var res = null;
        var th = threads.start(function () {
            res = scanForDuration(3000);
        });

        if (!isPause && running) {
            gesture(GESTURE_DURATION, [cx, cy], [lx, cy]);
        }

        sleep(2000);
        if (th) {
            try { th.join(); } catch (e) {}
        }

        if (!res && RETRY_COUNT > 0) {
            for (var i = 0; i < RETRY_COUNT; i++) {
                if (isPause || !running) return null;
                sleep(500);
                res = getDurationFromSeekBar();
                if (res) return res;
                var th2 = threads.start(function () {
                    res = scanForDuration(2000);
                });
                if (!isPause && running) {
                    gesture(GESTURE_DURATION, [cx, cy], [lx, cy]);
                }
                sleep(2000);
                if (th2) {
                    try { th2.join(); } catch (e) {}
                }
                if (res) return res;
            }
        }

        return res;
    } catch (e) {
        console.log("获取时长异常:" + e);
        return null;
    }
}

function getVideoDurationWithRetry() {
    var t = getVideoDuration();
    if (t) return t;
    sleep(800);
    return getVideoDuration();
}

// ============================================================
// 主循环
// ============================================================
function mainLoop() {
    var count = 0;
    while (running) {
        if (isPause) {
            sleep(300);
            continue;
        }

        count++;
        console.log("\n======= 第" + count + "个视频 =======");

        sleep(random(500, 1000));

        if (!hasSeekBar()) {
            console.log("图文内容,无进度条,直接上滑");
            swipeUp();
            continue;
        }

        var sec = getVideoDurationWithRetry();

        if (sec && sec > 0) {
            console.log("视频时长:" + sec + "秒 / 限制:" + LIMIT + "秒");
            if (sec > LIMIT) {
                console.log("长视频(>" + LIMIT + "秒),立即跳过");
                swipeUp();
            } else {
                var play = sec + 1;
                console.log("短视频,播放 " + play + " 秒");
                sleep(play * 1000);
                console.log("播放完毕,上滑");
                swipeUp();
            }
        } else {
            console.log("识别失败,10秒后跳过");
            sleep(10000);
            swipeUp();
        }
    }
}

// ============================================================
// 上滑操作
// ============================================================
function swipeUp() {
    if (isPause || !running) return;
    var baseX = device.width / 2;
    var randomX = baseX + random(-20, 20);
    var startY = device.height * 0.75 + random(-15, 15);
    var endY = device.height * 0.25 + random(-15, 15);
    var duration = random(300, 500);
    swipe(randomX, startY, randomX, endY, duration);
    sleep(700);
}

运行了一下,长视频直接跳过了
xxggla666 发表于 2026-5-7 07:56
xxggla666 发表于 2026-5-7 07:58
 楼主| lupaf 发表于 2026-5-7 11:28
xxggla666 发表于 2026-5-7 07:58
提问方式,直接把文档链接丢给他,照着写

感谢 我都试下 进度条时长都在进度条上方  50%会不会耗时更长
xxggla666 发表于 2026-5-7 12:16
lupaf 发表于 2026-5-7 11:28
感谢 我都试下 进度条时长都在进度条上方  50%会不会耗时更长

问问ai,一个一个测试,
 楼主| lupaf 发表于 2026-5-7 12:33
xxggla666 发表于 2026-5-7 12:16
问问ai,一个一个测试,

按您说的改多区域扫描 失败了 , 延长手势  没效果 ,原来的我都是尝试了几十次的,只有60%的成功率
 楼主| lupaf 发表于 2026-5-7 19:23
xxggla666 发表于 2026-5-7 16:34
/**
* 抖音长视频跳过脚本 - 精简版
*

真可以了  识别很准确 谢谢大佬

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
xxggla666 + 1 + 1 用心讨论,共获提升!

查看全部评分

您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-5-20 03:32

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表