使用Jersey在Java中为移动Safari浏览器提供mp3

使用Jersey在Java中为移动Safari浏览器提供mp3,java,mobile-safari,jax-rs,audio-streaming,html5-audio,Java,Mobile Safari,Jax Rs,Audio Streaming,Html5 Audio,我的代码有问题 @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 Respon

我的代码有问题

@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 mobile不能

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


如何让mobile Safari播放使用JAX-RS返回的音频?

我使用
AudioAttributes
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();
    }

我使用
AudioAttributes
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();
    }

你能澄清你的问题的根本原因是什么吗?我不太明白为什么对文件重新编码可以解决这个问题?据我所知,你有一个.mp3,它在Safari mobile中静态运行时效果很好,但按照上面的代码运行时效果不好。因此,我假设您的原始.mp3是以iOS可以处理的方式编码的(否则静态服务的文件将无法正确播放)


您与已送达的.mp3一起发送的标题是否有问题?我问这个问题的原因是,我在提供mp3到mobilesafari(由Perl脚本提供)时遇到了类似的问题。静态提供文件时工作正常。当使用Perl提供相同的文件时,Safari mobile会提供404(Safari on OSX工作正常)。

您能否澄清问题的根本原因是什么?我不太明白为什么对文件重新编码可以解决这个问题?据我所知,你有一个.mp3,它在Safari mobile中静态运行时效果很好,但按照上面的代码运行时效果不好。因此,我假设您的原始.mp3是以iOS可以处理的方式编码的(否则静态服务的文件将无法正确播放)


您与已送达的.mp3一起发送的标题是否有问题?我问这个问题的原因是,我在提供mp3到mobilesafari(由Perl脚本提供)时遇到了类似的问题。静态提供文件时工作正常。当使用Perl提供相同的文件时,Safari mobile会提供404(OSX上的Safari工作正常)。

当您将sample.mp3文件静态提供给Safari mobile时,是否有方法可以检查HTTP头?也许这些信息可以帮助我们了解safari mobile的期望。@broc.seib我从来没有跟进过这个问题。最后,我使用
AudioAttributes
EncodingAttributes
类将文件转换为正确的编解码器。如果有一个库可以检查文件的编解码器,并说出哪些设备可以播放它,那就太好了。稍后我将发布我的代码。当您将sample.mp3文件静态地提供给Safari mobile时,是否有方法可以检查HTTP头?也许这些信息可以帮助我们了解safari mobile的期望。@broc.seib我从来没有跟进过这个问题。最后,我使用
AudioAttributes
EncodingAttributes
类将文件转换为正确的编解码器。如果有一个库可以检查文件的编解码器,并说出哪些设备可以播放它,那就太好了。我马上发布我的代码。您需要支持字节范围请求。Apache和大多数其他静态文件服务器软件都支持它。您需要支持字节范围请求。Apache和大多数其他静态文件服务器软件都支持它。