2012-09-09 90 views
1

我有这个代码的麻烦在Java移动Safari浏览器,服务MP3使用泽西

@Path("/play") 
public class Player { 

    @GET 
    @Produces("audio/mpeg") 
    public Response get(@DefaultValue("C:\\Users\\Ben\\Music\\sample.mp3") @QueryParam("file") String file) { 
     File song = new File(file); 
     return Response.ok().entity(song).build(); 
    } 
} 

Chrome可以播放内容从这一返回,但Safari浏览器的手机无法。

当我将sample.mp3移动到静态web文件夹时,它可以在Safari移动浏览器中播放。

如何获取移动Safari以播放使用JAX-RS返回的音频?

+0

当您将sample.mp3文件静态地提供给Safari移动设备时,是否有办法检查HTTP标头?也许这个信息可以揭示Safari移动设备的期望。 –

+0

@ broc.seib我从来没有跟进过这个问题。我最终使用'AudioAttributes'和'EncodingAttributes'类将文件转换为正确的编解码器。如果有一个库可以检查文件的编解码器,并说出哪些设备可以播放它,那将会很不错。我会在一秒之内发布我的代码。 – sissonb

回答

1

我用​​和EncodingAttributes类将文件转换为正确的编解码器。这很慢,浪费了大量存储空间,因为每次播放歌曲时都必须创建一个新文件。我稍后可能会更改此代码,以便文件在转换后进行缓存。然后在我转换之前检查我是否已经转换。此外,在转换之前测试原始文件是否与设备兼容将会很好。这是目前的代码。

@GET 
    @Path("/audio") 
    @Produces("audio/mpeg") 
    public Response getAudio(
      @DefaultValue("C:\\Users\\Ben\\Music\\sample.mp3") @QueryParam("file") String file, 
      @DefaultValue("medium") @QueryParam("quality") String quality) throws EncoderException, IOException { 
     File song = new File(file); 
     File rootMusicDir = new File(AUDIO_PATH); 
     File rootVideoDir = new File(VIDEO_PATH); 
     if (!directoryService.isSubDirectory(rootMusicDir, song) && !directoryService.isSubDirectory(rootVideoDir, song)) { 
      return Response.status(500).build(); 
     } 

     AudioAttributes audio = new AudioAttributes(); 
     audio.setCodec("libmp3lame"); 
     if (quality.equalsIgnoreCase("high")) { 
      audio.setBitRate(new Integer(256000)); 
      audio.setChannels(new Integer(2)); 
      audio.setSamplingRate(new Integer(44100)); 
     } else if (quality.equalsIgnoreCase("medium")) { 
      audio.setBitRate(new Integer(128000)); 
      audio.setChannels(new Integer(2)); 
      audio.setSamplingRate(new Integer(44100)); 
     } else { 
      audio.setBitRate(new Integer(64000)); 
      audio.setChannels(new Integer(1)); 
      audio.setSamplingRate(new Integer(22050)); 
     } 

     EncodingAttributes attrs = new EncodingAttributes(); 
     attrs.setFormat("mp3"); 
     attrs.setAudioAttributes(audio); 
     Encoder encoder = new Encoder(); 

     String random = new BigInteger(130, new SecureRandom()).toString(32); 
     File songMP4 = new File(TEMP_PATH + file.replaceAll("[^\\dA-Za-z ]", "").replaceAll("\\s+", "+") + random); 
     encoder.encode(song, songMP4, attrs); 
     return Response.ok().entity(songMP4).build(); 
    } 
0

您能否澄清问题的根本原因是什么?我不太明白为什么重新编码文件应该解决问题?根据我的理解,你有一个.mp3,在静态服务的时候,在Safari移动设备上可以正常工作,但不能在按照上面的代码服务时使用。因此,我认为您的原始.mp3以iOS可以应付的方式进行编码(否则静态提供的文件将无法正确播放)。

您可能会遇到与您服务的.mp3一起发送的标题问题吗?我问的原因是,我有一个类似的问题,为一个Perl脚本提供的移动Safari提供mp3服务。静态提供文件时工作正常。当使用Perl提供相同的文件时,它会在Safari移动设备中提供404(OSX上的Safari工作正常)。

+0

您需要支持字节范围请求。 Apache和大多数其他静态文件服务器软件都支持它。 – idbehold