2016-04-20 42 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 –