I want to enable the user to play a sound. My implementation works fine with firefox. On Safari the sound is not played. I verified, that the audio control works in safari with other websites. So, I assume, that I will have to change something in my controller?
Controller:
@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);
}
View
<audio id="voice" controls="">
<source src="/sound/character/get/2">
</audio>
Firefox (works fine):
Safari (not working):
Most players are going to require a controller that supports partial content requests (or byte ranges).
This can be a little tricky to implement so I would suggest using something like the Spring Community Project Spring Content then you don't need to worry about how to implement the controller at all. The concepts and programming model are very similar to Spring Data's that, by looks of it, you are already using.
Assuming you are using Spring Boot (let me know if you are not) then it would look something like this:
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;
}
This is all you need to create a REST-based audio service at /characterSounds
supporting streaming. It actually supports full CRUD functionality as well; Create == POST, Read == GET (include the byte-range support that you need), Update == PUT, Delete == DELETE in case that is useful to you. Uploaded sounds will be stored in "/path/to/your/sounds".
So...
GET /characterSounds/{characterId}
will return a partial content response and this should stream properly in most, if not all, players (including seeking forwards and backwards).
HTH
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With