国语视界

 找回密码
 立即注册
查看: 5252|回复: 15

[蓝光技术] 如何跳过 狩猎.Jagten.2012 美版的进入菜单前的logo、trailer

[复制链接]

104

主题

733

帖子

1848

积分

营长

大洋
54244
阅读权限
50
发表于 20-2-24 18:12 | 显示全部楼层 |阅读模式
本帖最后由 filmfans 于 20-2-24 23:00 编辑

发行公司是Magnolia,这个厂牌太恐怖,长达10多分钟的前奏才能进入主菜单,用工具看了,貌似不是HDMV模式的,BD-J反编译也找不到切入点,有前辈能指点如何跳过logo、trailer播放吗?

13

主题

918

帖子

1313

积分

论坛大神

大洋
20750
阅读权限
130
发表于 20-2-24 23:02 | 显示全部楼层
00002.mpls 里的片头四个片子预告删了替换成一张1秒黑屏视频完事



回复 支持 反对

使用道具 举报

104

主题

733

帖子

1848

积分

营长

大洋
54244
阅读权限
50
 楼主| 发表于 20-2-24 23:24 | 显示全部楼层
我当时实在解不出来了,就想过用的你方法,但这是下策,在我手里95%的原盘我都能顺利跳过,这个没脾气了,一多半BD-J的都是写在配置文件里,硬编码到jar里貌似不多,因为这样很笨,无法通用,所以我想jar包里是不是还有配置文件
回复 支持 反对

使用道具 举报

2

主题

205

帖子

26

积分

禁止访问

大洋
12
阅读权限
0
发表于 20-3-4 23:50 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

46

主题

1475

帖子

3001

积分

版主

大洋
21045
阅读权限
140
发表于 20-3-12 14:48 | 显示全部楼层
本帖最后由 nnezyj 于 20-3-14 12:41 编辑

跳转写在了代码内!

打开 pw.class 文件,找到 public final void controllerUpdate(ControllerEvent controllerEvent) 函数
在 if (controllerEvent instanceof EndOfMediaEvent) {} 的代码段里
找到 np.s == 505 的判定段,修改 np.d(3) 为 np.d(0)

                    } else if (np.s == 505) {
                        np.d(3);
                    }

np.d(int TitleNumber) 的调用语句,用于跳转到指定 Title
TopMenu Title = 0

上面的修改方法,是让播放机在播放完毕 PlayList#505 的 Logo 视频后,跳转到 TopMenu 主菜单 Title



跳过logo、trailer播放


如果,需要一开始就直接进入 TopMenu 主菜单 Title。

理论上应该由 FirstPlayback Title 内的 HDMV 指令直接跳转至 TopMenu。
MO#0 第 2179 行指令:
  Move GPR4075 1;
  Jump Title GPR4075;
FirstPlayback 为 HDMV Title,这个可以使用 BDedit 查看原盘结构。

查看过代码,这种直接跳转不可行,因为代码内,首次运行 BD-J 程序,默认是依旧是会播放 PlayList#505 的,然后再执行相应 Title 跳转。
【这里排除掉区码不对、已播放过的原盘再次播放等干扰因素】

代码修改方法:

打开 MagnoliaTheHunt.class 文件,找到 private static void b(boolean z) 函数
找到 np.c(505); 的调用语句,修改 np.c(505); 为 np.d(0);

        } else if (z) {
            np.c(505); /* np.c(int playlistId) | "bd://PLAYLIST:00505" */
        }

np.c(int playlistId) 的调用语句,用于播放指定编号的 PlayList 视频



=============================分隔符==================================
以上代码修改方法,虽然可以跳转到 TopMenu Title,但相关的菜单显示及控制类没有运行
回复 支持 反对

使用道具 举报

104

主题

733

帖子

1848

积分

营长

大洋
54244
阅读权限
50
 楼主| 发表于 20-3-12 19:06 | 显示全部楼层
牛逼 我会找时间试试,感谢,有时间试试
回复 支持 反对

使用道具 举报

46

主题

1475

帖子

3001

积分

版主

大洋
21045
阅读权限
140
发表于 20-3-14 00:48 | 显示全部楼层
本帖最后由 nnezyj 于 20-3-14 13:18 编辑
nnezyj 发表于 20-3-12 14:48
跳转写在了代码内!

打开 pw.class 文件,找到 public final void controllerUpdate(ControllerEvent cont ...


我做了实际测试,虽然可以跳转,但是菜单不可操作!
因为 Title#3 会执行菜单加载进程。

直接修改跳到 TopMenu Title,没有相应的菜单加载代码运行,菜单便不可操作。


--------------------------------------------------------
以下是代码说明:

pw.class 的 public final void controllerUpdate(ControllerEvent controllerEvent) 函数
在 controllerEvent instanceof MediaPresentedEvent 代码段下
调用的 gy.class 内执行与菜单相关的加载代码

                                if (is.a(4) == 3) {
                                    if (lu.a() == 514) {
                                        new gy().a(9000L);
                                    }
                                }


gy extends TimerTask ,gy是一个计时器任务,在循环计时,直到菜单相关的函数都加载完毕,之后跳转 Title#4
在 gy.class 类的 public final void run() {} 代码段里,最后的语句 np.d(4); 就是执行完毕后跳转到 Title#4

Title#4 播放 PlayList#513,即预告片
--------------------------------------------------------

原盘的播放顺序:
FirstPlayback --> Title#1 PlayList#505 Logo视频 --> Title#3 PlayList#514 --> Title#4 PlayList#513 预告片 --> Title#5 PlayList#508 --> TopMenu PlayList#500 主菜单

-----------------------------------------------------

如果保留播放 Logo,然后播放 MPLS#514 警告视频,然后就进入主菜单

那么,只用修改 gy.class 文件 public final void run() {} 代码的 np.d(4); 为 np.d(0);

------------------------------------------------------
修改 gy.class 测试成功!

===========================分隔符==============================
若是不播放 Logo,直接进入主菜单
除了修改 gy.class 文件 public final void run() {} 代码的 np.d(4); 为 np.d(0);
还要修改 MagnoliaTheHunt.class 文件,
找到 MagnoliaTheHunt.class 文件的 private static void b(boolean z) 函数
找到 np.c(505); 的调用语句,修改 np.c(505); 为 new gy().a(9000L);


此测试不成功!

播放直接进入主菜单,还需要修改其他地方,没心思折腾了……
=========================================================
回复 支持 反对

使用道具 举报

46

主题

1475

帖子

3001

积分

版主

大洋
21045
阅读权限
140
发表于 20-3-14 01:31 | 显示全部楼层
链接: https://pan.baidu.com/s/1fls4jlgI7pGCMxI4fs-ZiQ 提取码: y9rh

jar文件及证书等
回复 支持 反对

使用道具 举报

104

主题

733

帖子

1848

积分

营长

大洋
54244
阅读权限
50
 楼主| 发表于 20-3-15 23:04 | 显示全部楼层
看来还需进一步研究 谢谢@nnezyj指导,还有哪位高手可以再试试,不胜感激
回复 支持 反对

使用道具 举报

104

主题

733

帖子

1848

积分

营长

大洋
54244
阅读权限
50
 楼主| 发表于 20-4-24 21:37 | 显示全部楼层
本帖最后由 filmfans 于 20-4-24 21:45 编辑

今天花了一整天的时间折腾,反复修改,已经找到最核心的代码,理论上如果修改对了,所有问题都解决了,但是尝试了各种方法来改,都没成功,说白了,还是功力太浅!现整理一下思路,精读了《Magnolia Pictures-狩猎-BD_BDJ-菜单修改》这篇教程,最后反复琢磨,定位到了TitleChangeImplement.class  Title切换-具体实现类

如果把进入每个title播放的关键代码lu.a(#playlist ID)去掉,虽然可以跳过播放,但会导致链式播放中断,即播放当前playlist完毕,系统要知道当前播放的#playlist ID,否则系统无法继续往下继续播放,仔细看了lu.a的代码,播放前要设置np.s=#playlist ID,告诉系统当前播放的是哪个playlist,所以屏蔽lu.a同时,加上一行np.s=#playlist ID,但测试结果还是不成,界面黑屏停留不动,我估计还是我修行不够,思路对,代码改的可能有问题

另外的问题:按照版主nnezyj 《BD-J 的 Scenarist 工具重编译及重签名.chm》教程编译TitleChangeImplement.java,试用所有能找到的大金版本,都会导致编译虽然没有提示错误,而且编译成功,但通过反编译工具jd-gui完全无法逆向,软件提示一堆错误,但象nnezyj 之前修改的gy.java 这种代码量很少的 我这里也顺利编译,并且正确逆向、执行,不知道什么原因,光这个就折腾很久,还是不行,最后都是直接修改字节码,与编译效果都是一样的。只能采取这种下策了


                    if (n == 2) { <== 进入title#2执行的代码,可以看到仅是播放logo
                        if (np.C && np.a.getState() == 600) {
                            np.p();
                        }
                        if (is.b(11) == 0) {
                            lu.a(505);
                            is.a(10, 0);
                            bs.a(false);
                        }
                        else {
                            np.c(505);
                            is.a(10, 0);
                            bs.a(false);
                        }
                    }
                    else if (n == 3) {  <== 进入title#3执行的代码,可以看到仅是播放警告
                        if (np.a.getState() == 600) {
                            np.p();
                        }
                        if (!ja.c()) {
                            lu.a(514);
                        }
                        else {
                            lu.a(507);
                        }
                    }
                    else if (n == 4) {
                        if (np.C && np.a.getState() == 600) { <== 进入title#4执行的代码,可以看到仅是播放trailer
                            np.p();
                        }
                        if (!np.C) {
                            np.c(513);
                        }
                        else {
                            lu.a(513);
                        }
                    }
                    else if (n == 5) {
                        if (np.a.getState() == 600) { <== 进入title#5执行的代码,可以看到仅是播放最后一个广告
                            np.p();
                        }
                        lu.a(508);
                    }
                    else if (n == 6) {  <== 进入title#6执行的代码,最后一行执行feature(正片)之前的DTS演示
                        if (np.C && np.a.getState() == 600) {
                            np.p();
                        }
                        bd.a(false);
                        Label_0975: {
                            if (aa.a()) {
                                fd.a(true);
                                lu.a(f.q);
                                np.e(3);
                                aa.a(false);
                            }
                            else if (pl.b()) {
                                pl.a();
                            }
                            else {
                                if (ai.b()) {
                                    v.d();
                                    if (!bs.b()) {
                                        fd.a(true);
                                        ai.a(false);
                                        lu.a(f.q, ai.a());
                                        break Label_0975;
                                    }
                                }
                                else {
                                    if (on.c()) {
                                        on.a(false);
                                        lu.a(on.a(), on.b());
                                        break Label_0975;
                                    }
                                    if (v.f()) {
                                        v.d();
                                        v.c();
                                        break Label_0975;
                                    }
                                    if (is.b(105) != 0) {
                                        is.a(105, 0);
                                        final long b = ij.b();
                                        final int c = ij.c();
                                        int d;
                                        if ((d = ij.d()) == 3) {
                                            d = 1;
                                        }
                                        final int e = ij.e();
                                        final boolean f = ij.f();
                                        fd.a(true);
                                        np.c(c);
                                        np.a(new Time(b));
                                        np.e(d);
                                        np.f(e);
                                        np.c(f);
                                        ij.a();
                                        is.a(11, 0);
                                        bs.a(true);
                                        break Label_0975;
                                    }
                                    if (is.b(101) != 0) {
                                        final long b2 = ij.b();
                                        final int c2 = ij.c();
                                        final int d2 = ij.d();
                                        final int e2 = ij.e();
                                        final boolean f2 = ij.f();
                                        fd.a(true);
                                        np.c(c2);
                                        np.a(new Time(b2));
                                        np.e(d2);
                                        np.f(e2);
                                        np.c(f2);
                                        ij.a();
                                        is.a(11, 0);
                                        bs.a(true);
                                        break Label_0975;
                                    }
                                    if (ij.g() && is.b(11) == 500) {
                                        fw.a(0, 0, 1920, 1080, new Color(0, 0, 0, 255));
                                        fw.a(0, 0);
                                        de.a(0, 0, 1920, 1080);
                                        fw.d();
                                        final long b3 = ij.b();
                                        final int c3 = ij.c();
                                        final int d3 = ij.d();
                                        final int e3 = ij.e();
                                        final boolean f3 = ij.f();
                                        fd.a(true);
                                        np.e(d3);
                                        np.f(e3);
                                        np.c(f3);
                                        np.c(c3);
                                        np.a(new Time(b3));
                                        break Label_0975;
                                    }
                                    if (ij.g() && is.b(1015) != 0) {
                                        is.a(1015, 0);
                                        final long b4 = ij.b();
                                        final int c4 = ij.c();
                                        final int d4 = ij.d();
                                        final int e4 = ij.e();
                                        final boolean f4 = ij.f();
                                        fd.a(true);
                                        lu.a(c4, b4);
                                        np.e(d4);
                                        np.f(e4);
                                        np.c(f4);
                                        ij.a();
                                        is.a(10, 500);
                                        bs.a(true);
                                        break Label_0975;
                                    }
                                    if (bs.a()) {
                                        fd.a(true);
                                        lu.a(f.q);
                                        break Label_0975;
                                    }
                                }
                                fd.a(true);
                                lu.a(509);
                            }
回复 支持 反对

使用道具 举报

46

主题

1475

帖子

3001

积分

版主

大洋
21045
阅读权限
140
发表于 20-4-25 02:19 | 显示全部楼层
filmfans 发表于 20-4-24 21:37
今天花了一整天的时间折腾,反复修改,已经找到最核心的代码,理论上如果修改对了,所有问题都解决了,但是 ...

建议你比对着《Magnolia Pictures-狩猎-BD_BDJ-菜单修改》,对全盘代码做一次图表关系整理!


如果把进入每个title播放的关键代码lu.a(#playlist ID)去掉,虽然可以跳过播放,但会导致链式播放中断,即播放当前playlist完毕,系统要知道当前播放的#playlist ID,否则系统无法继续往下继续播放,仔细看了lu.a的代码,播放前要设置np.s=#playlist ID,告诉系统当前播放的是哪个playlist,所以屏蔽lu.a同时,加上一行np.s=#playlist ID,但测试结果还是不成,界面黑屏停留不动,我估计还是我修行不够,思路对,代码改的可能有问题


并不是你想象的那样!每一次视频播放,都会触发一个叫侦听机制的设计!

首先,播放 Logo 视频,会触发一个播放事件,这个事件发送给其他函数!
通过判定,当前播放 Logo 视频,执行在此时应该执行的预设步骤,在后台加载图片!
播放完 Logo 视频!跳转下一个 Title,播放 Warning 视频。

播放 Warning 视频,再次触发一个播放事件,这个事件发送给其他函数!
通过判定,通过判定,当前播放 Warning 视频,执行在此时应该执行的预设步骤,在后台初始化菜单!
播放完 Warning 视频!跳转下一个 Title,播放后续视频。

后续视频,通过我对代码的阅读,不会有其他的小动作了,就是纯播放视频,直到最后进入主菜单!


============ 分隔符 ===========
以上是我阅读代码,和实际测试后,得到的一个运行记录!

不知道,你是否看明白了!

前两个视频在播放的时候,同时的,在程序后台,还执行了从光盘上对加载图片文件,初始化主菜单及各子菜单等的操作!
============ 分隔符 ===========

如果,想要不播放在主菜单前的所有视频!

那么,你需要以下操作:
1、找到前面和播放视频关联起来的,最重要的两个后台程序:图片加载、菜单初始化!
2、将这些函数,放到整个原盘加载进程中去,让它们在原盘加载的一刻起,就开始运行!



这些函数是哪些?
《Magnolia Pictures-狩猎-BD_BDJ-菜单修改》 文件里,已经把运行的流程解析过了!

现在,你还剩下一个最重要的问题,你需要重构代码,因为所有的运行都与播放视频交错在一起的!
1、你首先需要把它们几个函数的运行关系,画出一张图表!
2、根据图标剔除,不要的视频播放的代码
3、因为去掉播放代码的关系,以下几个关键内容失去了关联:原盘播放加载、图片加载、菜单初始化、进入主菜单
4、很重要:你要自己编写代码,把它们关联起来!
5、测试




回复 支持 反对

使用道具 举报

104

主题

733

帖子

1848

积分

营长

大洋
54244
阅读权限
50
 楼主| 发表于 20-4-25 08:52 | 显示全部楼层
本帖最后由 filmfans 于 20-4-25 09:30 编辑

关于重构代码,您还别说,我就是在今天凌晨躺在床上未睡之前,还想过这件事,需要的工作量太大,不能不说原代码的作者还是很牛逼,估计他已经意识到后人会对他的代码动手脚,好吧!让你们动,我把代码拆散,弄死你们,哈哈!

我在看菜单那个教程时,我在想你为什么要用两个反编译的工具来看,在我实践中才发现比如上文提到的那个titlechange单元两个工具,各自只能正确还原一个函数代码,得组合在一起看,真有意思!

另外,我说的用大金bd-j模块编译不提示错误,但实际不能正确反编译,您那里遇到了吗
回复 支持 反对

使用道具 举报

46

主题

1475

帖子

3001

积分

版主

大洋
21045
阅读权限
140
发表于 20-4-28 09:57 | 显示全部楼层
filmfans 发表于 20-4-25 08:52
关于重构代码,您还别说,我就是在今天凌晨躺在床上未睡之前,还想过这件事,需要的工作量太大,不能不说原 ...

不能反编译,这个不太清楚。
理论上,通过 java 文件编译生成的 class 文件,没有经过混淆处理,其内部的各种字段都完整,反编译此 class 文件,应该是没有问题的!
回复 支持 反对

使用道具 举报

46

主题

1475

帖子

3001

积分

版主

大洋
21045
阅读权限
140
发表于 20-5-3 18:31 | 显示全部楼层

这是我的 MagnoliaTheHunt.java 与 TitleChangeImplement.java 文件。

这是编译出来的 MagnoliaTheHunt.class 与 TitleChangeImplement.class 文件。


TitleChangeImplement.java 编译出来的 TitleChangeImplement.class 文件,反编译测试:
  jd-gui 1.6.6 不能正确反编译出 java 代码。
  jd-gui 1.4.0 可以正确反编译出 java 代码。
  jadx-1.1.0 可以正确反编译出 java 代码。
反编译工具的反编译设计,每个工具的反编译设计可能有所不同,版本高低也有作者反编译理念的变化,纠结这个没意思,找到能反编译成功的就行!
本身反编译就不是官方的,都是第三方!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复 支持 反对

使用道具 举报

13

主题

1316

帖子

256

积分

排长

大洋
9840
阅读权限
30
发表于 20-6-7 04:36 | 显示全部楼层
nnezyj 发表于 20-5-3 18:31
这是我的 MagnoliaTheHunt.java 与 TitleChangeImplement.java 文件。

这是编译出来的 MagnoliaTheHunt.c ...

白师傅、我被你的耐心折服了、真的、真的大佬、有问必答
论坛有你、真的是大家的福分、真心感谢
回复 支持 反对

使用道具 举报

7

主题

2169

帖子

1206

积分

营长

大洋
473
阅读权限
50
发表于 21-4-30 21:43 | 显示全部楼层
原来是这样谢谢
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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