2016-04-20 23 views
1

我正在写一个实用程序使用基于开放源码的Java的PDFBox转换PDF文件包含“超链接打开一个MP3文件”,以取代声音对象。PDFBox创建声音对象与链接/参考外部的MP3或WAV文件

我使用PDFBox API,因为它看起来足够成熟,可以使用Sound对象。我可以阅读PDF文件,并找到参考mp3的超链接。但我无法用声音对象取代它。我创建了声音对象并与操作相关联,但它不起作用。我想我错过了一些重要的部分如何使用PDActionSound对象创建Sound对象。使用PDFBox API可以引用外部wav文件吗?

for (PDPage pdPage : pages) { 
    List<PDAnnotation> annotations = pdPage.getAnnotations(); 
    for (PDAnnotation pdAnnotation : annotations) { 
     if (pdAnnotation instanceof PDAnnotationLink) { 
      PDAnnotationLink link = ((PDAnnotationLink) pdAnnotation); 
      PDAction action = link.getAction(); 
      if (action instanceof PDActionLaunch) { 
       PDActionLaunch launch = ((PDActionLaunch) action); 
       String fileInfo = launch.getFile().getFile(); 
       if (fileInfo.contains(".mp3")) { 
       /* create Sound object referring to external mp3*/ 
       //something like 
       PDActionSound actionSound = new PDActionSound(
             soundStream); 
       //set the ActionSound to the link. 
       link.setAction(actionSound); 
       } 
      } 
     } 
    } 
} 

如何创建声音对象(PDActionSound)并添加到链接成功?

回答

1

说到成熟,那部分从来没有被使用过,现在我仔细看了一下代码,我认为还有一些工作要做......请试试这个,我在阅读完PDFBox 2.0后创建了这个PDF规范:

PDSimpleFileSpecification fileSpec = new PDSimpleFileSpecification(new COSString("/C/dir1/dir2/blah.mp3")); // see "File Specification Strings" in PDF spec 
COSStream soundStream = new COSStream(); 
soundStream.createOutputStream().close(); 
soundStream.setItem(COSName.F, fileSpec); 
soundStream.setInt(COSName.R, 44100); // put actual sample rate here 
PDActionSound actionSound = new PDActionSound(); 
actionSound.getCOSObject().setItem(COSName.getPDFName("Sound"), soundStream)); 
link.setAction(actionSound); // reassign the new action to the link annotation 

编辑:如上面没有工作,这里是作为意见要求的替代解决方案。该文件已嵌入。它只适用于.WAV文件,你必须知道它们的细节。大约1/2秒在开始时丢失。你应该听到的声音是“我是Al Bundy”。我试着用MP3,但没有成功。当用谷歌搜索时,我发现一些文本说只有“旧”格式(wav,aif等)被支持。我确实找到了另一种播放声音的方式(“Renditions”),它甚至在another product中与嵌入式mp3一起工作,但PDF中生成的结构更加复杂。

COSStream soundStream = new COSStream(); 
OutputStream os = soundStream.createOutputStream(COSName.FLATE_DECODE); 
URL url = new URL("http://cd.textfiles.com/hackchronii/WAV/ALBUNDY1.WAV"); 
InputStream is = url.openStream(); 
// FileInputStream is = new FileInputStream(".....WAV"); 
IOUtils.copy(is, os); 
is.close(); 
os.close(); 
// See p. 506 in PDF spec, Table 294 
soundStream.setInt(COSName.C, 1); // channels 
soundStream.setInt(COSName.R, 22050); // sampling rate 
//soundStream.setString(COSName.E, "Signed"); // The encoding format for the sample data 
soundStream.setInt(COSName.B, 8); // The number of bits per sample value per channel. Default value: 8 
// soundStream.setName(COSName.CO, "MP3"); // doesn't work 
PDActionSound actionSound = new PDActionSound(); 
actionSound.getCOSObject().setItem(COSName.getPDFName("Sound"), soundStream); 
link.setAction(actionSound); 

更新2016年9月7日:

我们的PDFBox的邮件列表上讨论了这一点,并感谢吉拉德Denneboom我们知道两两件事: 1)在Adobe Acrobat中,只允许你选择WAV或AIF文件 2)由吉拉德Denneboom代码MP3SPI到MP3转换成原材料:

private static InputStream getAudioStream(String filename) throws Exception { 
    File file = new File(filename); 
    AudioInputStream in = AudioSystem.getAudioInputStream(file); 
    AudioFormat baseFormat = in.getFormat(); 
    AudioFormat decodedFormat = new AudioFormat(
     AudioFormat.Encoding.PCM_UNSIGNED, 
     baseFormat.getSampleRate(), 
     baseFormat.getSampleSizeInBits(), 
     baseFormat.getChannels(), 
     baseFormat.getChannels(), 
     baseFormat.getSampleRate(), 
     false); 
    return AudioSystem.getAudioInputStream(decodedFormat, in); 
} 
+0

谢谢您的回答。 ActionSound有setItem方法吗?您正在使用哪种版本的PDXBox API? –

+0

我使用的是2.0。我忘了添加getCOSObject(),对不起,我编辑了我的答案。 (如果你的问题得到解决,我会注意将来添加setSound()方法)。 –

+0

谢谢@Tilman不幸的是它还没有解决。我有另一个声音对象(手动添加)..当我播放该声音对象时,它会播放声音,并按照您的解决方案以编程方式创建声音注释时,它会停止正在播放的声音。但它不播放我附加使用的文件.. 'PDSimpleFileSpecification fileSpec = new PDSimpleFileSpecification(“D:\ temp.wav”);' 我使用PDXBox 2.0.0 RC3 API –