Spring-MVC:如何从控制器流式传输 mp3 文件

Posted

技术标签:

【中文标题】Spring-MVC:如何从控制器流式传输 mp3 文件【英文标题】:Spring-MVC : How to stream mp3 file from controller 【发布时间】:2018-08-29 02:40:05 【问题描述】:

我正在开发一个 Spring-MVC 应用程序,我正在尝试在其中流式传输 mp3 数据。不幸的是,只要发送一个字节数组的信息作为响应,它就会直接触发下载。我发现了一些其他链接,但其中大多数都与用户界面相关联,因此没有多大用处。流式传输 mp3 文件有什么要求?这是我的下载代码。

 @RequestMapping(value = "/getsong/token")
    public ResponseEntity<byte[]> getsong(@PathVariable("token") String token, HttpServletResponse response) 
        try 
                Path path = Paths.get(FILE_LOCATION);
                response.setContentType("audio/mp3");
                response.setHeader("Content-Disposition", "attachment; filename=\"" + "song.mp3" + "\"");
                response.setContentLength((int) Files.size(path));
                Files.copy(path, response.getOutputStream());
                response.flushBuffer();

         catch (Exception ignored) 
        
        return null;
    

谢谢。

【问题讨论】:

如果它是 mp3 文件,您为什么要将 ContentType 设置为“image/png”,您正在响应?如果添加“Content-Disposition”、“attachment”,系统将始终提示您保存文件。 @jarst :好的,错误。我应该怎么设置?音频/mp3? 也许音频/mpeg 会更合适并移除 Content Disposition。 @jarst :仍然不起作用。仍然会下载。 【参考方案1】:

您现在可能已经解决了这个问题。但仍然只是想在这里添加我的评论 - 您正在将“附件”设置为 Content-Disposition 标头。我认为这就是导致每次调用此代码时它都会下载的原因。

【讨论】:

我刚刚在自己的项目中验证了这一点。 Content-Disposition 标头是触发下载提示的原因。【参考方案2】:

您没有提及您的客户端/播放器是什么,但大多数播放器都需要支持部分内容请求(或字节范围)的控制器。

这可能有点难以实现,所以我建议使用Spring Content 之类的东西。那么你根本不需要担心如何实现控制器代码。假设您使用的是 Spring Boot(如果不是,请告诉我),那么它看起来像这样:

pom.xml

<dependency>
    <groupId>com.github.paulcwarren</groupId>
    <artifactId>spring-content-rest-boot-starter</artifactId>
    <version>0.0.10</version>
</dependency>
<dependency>
    <groupId>com.github.paulcwarren</groupId>
    <artifactId>content-fs-spring-boot-starter</artifactId>
    <version>0.0.10</version>
</dependency>

SpringBootApplication.java

@SpringBootApplication
public class YourSpringBootApplication 

  public static void main(String[] args) 
    SpringApplication.run(YourSpringBootApplication.class, args);
  

  @Configuration
  @EnableFilesystemStores
  public static class StoreConfig 
    File filesystemRoot() 
        return new File("/path/to/your/songs");
    

    @Bean
    public FileSystemResourceLoader fsResourceLoader() throws Exception 
      return new FileSystemResourceLoader(filesystemRoot().getAbsolutePath());
    
  

  @StoreRestResource(path="songs")
  public interface SongsStore extends Store<String> 
    //
  

这就是您在/songs 创建支持流媒体的基于 REST 的电影服务所需的全部内容。它实际上也支持完整的 CRUD 功能;创建 == POST,读取 == GET(包括字节范围支持),更新 == PUT,删除 == DELETE,以防万一对您有用。上传的歌曲将存储在“/path/to/your/songs”中。

所以...假设您的服务器上有/path/to/your/songs/example-song.mp3 然后:

GET /songs/example-song.mp3

将返回部分内容响应,这应该在大多数(如果不是全部)播放器中正常播放(包括向前和向后搜索)。

HTH

【讨论】:

为什么要隐藏实际的歌曲文件路径/名称?我问的原因是因为 Spring Content 支持其他类型的 Store,它们也允许您拥有这种 URL。无论如何,让我知道。

以上是关于Spring-MVC:如何从控制器流式传输 mp3 文件的主要内容,如果未能解决你的问题,请参考以下文章

如何以 mp3 格式从麦克风流式传输声音?

如何在使用 NAudio 流式传输 mp3 时获取当前时间?

如何将媒体文件从服务器流式传输到客户端,例如我在 loopback 4 nodejs 中的 mp3 音频文件?

从 Amazon S3 流式传输 MP3

在 Swift 3 中从服务器流式传输 mp3 文件

将 mp3 从服务器流式传输到 html5 音频时传递持续时间