如何使用 Spring Boot 流式传输音频

Posted

技术标签:

【中文标题】如何使用 Spring Boot 流式传输音频【英文标题】:How to stream audio with spring boot 【发布时间】:2019-07-01 08:19:29 【问题描述】:

我想让用户播放声音。我的实现适用于 Firefox。在 Safari 上不播放声音。我验证了音频控制在 Safari 中与其他网站一起工作。所以,我认为,我将不得不更改控制器中的某些内容?

控制器:

@RequestMapping(value = "/sound/character/get/characterId", method = RequestMethod.GET, produces = 
            MediaType.APPLICATION_OCTET_STREAM_VALUE )
        public ResponseEntity playAudio(HttpServletRequest request,HttpServletResponse response, @PathVariable("characterId") int characterId) throws FileNotFoundException

        logger.debug("[downloadRecipientFile]");

        de.tki.chinese.entity.Character character = characterRepository.findById(characterId);
        String file = UPLOADED_FOLDER + character.getSoundFile();

        long length = new File(file).length();


        InputStreamResource inputStreamResource = new InputStreamResource( new FileInputStream(file));
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentLength(length);
        httpHeaders.setCacheControl(CacheControl.noCache().getHeaderValue());
        return new ResponseEntity(inputStreamResource, httpHeaders, HttpStatus.OK);
    

查看

        <audio id="voice" controls="">
            <source src="/sound/character/get/2">
        </audio>

Firefox(工作正常):

Safari(不工作):

【问题讨论】:

【参考方案1】:

大多数播放器都需要支持部分内容请求(或字节范围)的控制器。

这实现起来可能有点棘手,所以我建议使用 Spring Community Project Spring Content 这样的东西,那么您根本不需要担心如何实现控制器。概念和编程模型与您已经在使用的 Spring Data 非常相似。

假设您使用的是 Spring Boot(如果没有,请告诉我),那么它看起来像这样:

pom.xml

<!-- Java API -->
<dependency>
    <groupId>com.github.paulcwarren</groupId>
    <artifactId>content-fs-spring-boot-starter</artifactId>
    <version>0.6.0</version>
</dependency>
<!-- REST API -->
<dependency>
    <groupId>com.github.paulcwarren</groupId>
    <artifactId>spring-content-rest-boot-starter</artifactId>
    <version>0.6.0</version>
</dependency>

SpringBootApplication.java

@SpringBootApplication
public class YourSpringBootApplication 

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

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

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

  @StoreRestResource(path="characterSounds")
  public interface SoundsContentStore extends ContentStore<UUUID,String> 
    //
  

Charater.java

public class Character 

    @Id
    @GeneratedValue
    private Long id;

    ...other existing fields...

    @ContentId
    private UUID contentId;

    @ContentLength
    private Long contnetLength;

    @MimeType
    private String mimeType;
 

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

所以...

GET /characterSounds/characterId

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

HTH

【讨论】:

【参考方案2】:

另一种解决方案(对我来说很容易实现,只需对我现有的代码稍作改动)就在这里:

https://github.com/spring-projects/spring-framework/blob/v4.2.0.RC1/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java#L463

【讨论】:

Spring Content 在内部使用 @tobi。很高兴你有一些工作。【参考方案3】:

你可以在java中使用这个代码

void sound(String path) 
    File lol = new File(path);
    try 
        Clip clip = Audiosystem.getClip();
        clip.open(AudioSystem.getAudioInputStream(lol));
        clip.start();
     catch (Exception e) 
        e.printStackTrace();
    

【讨论】:

以上是关于如何使用 Spring Boot 流式传输音频的主要内容,如果未能解决你的问题,请参考以下文章

如何使用来自网络套接字的网络音频 API 流式传输音频块?

如何在 swift 中使用 cocoahttpserver 流式传输音频(设备歌曲)?

如何使用 swift 仅在已知持续时间内流式传输音频

如何让 Actions on Google 流式传输音频?

如何实时流式传输音频文件

如何在 iOS swift 中使用 UDP 套接字流式传输音频?