去年,我在讲座中加入了背景音乐和一种“激光指示器”(与声音同步)。我使用投影幻灯片、大量 pstricks 以及始终采用 Latex->dvips->ps2pdf 工作流程。“激光指示器”通过 pdf 中的“圆形注释”(不透明度为 0.5)实现。
因此,我编写了一个命令 \plusaudio,它将 mp3 文件名作为第一个参数,将“激光指示器”的时间和位置数据作为第二个参数,例如:
\plusaudio{Kapitel1_NT_0003_einf01_1}{[[0],[7034,[137,243,172,208]],[10118,[302,242,337,207]],[10119],…}
(此处注释从 7034ms 到 10118ms 可见,注释的边界框从 [137,243,172,208] 移动到 [302,242,337,207],在 10119ms 时注释切换为不可见)
第一个参数(mp3 文件)从 media9 包传递给 \includemedia,第二个参数(时间和位置数据)通过页面打开的 javascript 传递给“Widget Annotation”,从而设置包含时间和位置数据的 jacascript 变量“LPTimingArray”。
其余编程是在 pdf 的 javascript 端完成的:
- 每 100 毫秒启动一次间隔计时器
- 使用 callAS("currentTime") 方法获取媒体播放的当前时间
- 搜索 LPTimingArray 中圆圈注释是否可见以及在何处可见/不可见
通过 callAs 函数(pdf 的 javascript 端),始终可以保证声音和“激光指示器”的同步,并且我添加了暂停/播放、快进和快退按钮。
由于 2021 年关闭了 Flash,此方法不再有效。我找到了另一种嵌入和播放声音的方法(请参阅我的帖子Media9 将于 2020 年 12 月淘汰。有没有在 LaTeX 中嵌入视频/音频的替代方法?)声音由“媒体演绎”控制。
对于我的“激光笔”功能,所有控制都位于 pdf 的 javascript 区域中。播放/暂停、倒带和快进按钮由 mediaplayer 方法播放、暂停和搜索实现(请参阅https://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/js_api_reference.pdf,第 505 页)。在 Windows 中,使用“vnd.adobe.swname:MSFT_WindowsMediaPlayer”可以正常工作,但使用“vnd.adobe.swname:ADBE_MCI”则无法搜索。但是,仍存在一个问题:
要使用 javascript 访问媒体版本,pdf 文件的目录“/Names”字典中必须有一个“/Renditions”名称树条目。我通过以下方式完成此操作
\special{ps:: SDict~begin~[~{Catalog}~<</Names~<</Renditions~\pbs_pdflastobj:>>~>>~/PUT~pdfmark~end}
(\pbs_pdflastobj:是版本名称树数组)。
使用此方法,所有媒体和“激光笔”控制都可以正常工作,但(这是剩下的问题)“/Dests”名称树丢失,文档中所有指向目标的链接都不再起作用。删除此行代码后,“/Dests”名称树会插入,但“/Renditions”名称树不会插入(因此,我通过 javascript 对媒体的控制不起作用)。“Acrobat Distiller”和“ps2pdf”都存在这种情况。
我找到了一个解决方法,但应该有一种方法可以简化这个过程。在我的解决方法中,我没有在 postscript 中插入再现名称树(删除上面的代码行),但是
1.) 使用“Acrobat Distiller”制作 pdf 的第一个版本(包含“/Dests”名称树)
2.) 使用“qpdf”和“--object-streams=disable”可获得几乎 ASCII 版本的 pdf
3.) 使用自编的 c 程序,用“/Renditions”名称树扩展此 ASCII pdf(并更新 xref 表)
4.) 再次使用“qpdf”和“--compress-streams=y”来获取与第一步文件大小相当的 pdf
有人有办法解决这个问题吗?
问候,弗里茨