Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
8282054: Mediaplayer not working with HTTP Live Stream link with quer…
…y parameter appended with file extension m3u8

Reviewed-by: kcr, arapte
  • Loading branch information
Alexander Matveev committed Apr 12, 2022
1 parent 6d12638 commit d1110f4
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 38 deletions.
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2010, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -422,7 +422,7 @@ public void init() throws URISyntaxException, IOException, FileNotFoundException
InputStream stream = getInputStream(uri);
stream.close();
isConnected = true;
contentType = MediaUtils.filenameToContentType(uriString); // We need to provide at least something
contentType = MediaUtils.filenameToContentType(uri.getPath()); // We need to provide at least something
}

if (isConnected) {
Expand All @@ -438,7 +438,7 @@ public void init() throws URISyntaxException, IOException, FileNotFoundException
} else {
if (contentType == null || !MediaManager.canPlayContentType(contentType)) {
// Try content based on file name.
contentType = MediaUtils.filenameToContentType(uriString);
contentType = MediaUtils.filenameToContentType(uri.getPath());

if (Locator.DEFAULT_CONTENT_TYPE.equals(contentType)) {
// Try content based on file signature.
Expand Down Expand Up @@ -469,7 +469,7 @@ public void init() throws URISyntaxException, IOException, FileNotFoundException
}
else {
// in case of iPod files we can be sure all files are supported
contentType = MediaUtils.filenameToContentType(uriString);
contentType = MediaUtils.filenameToContentType(uri.getPath());
}

if (Logger.canLog(Logger.WARNING)) {
Expand Down Expand Up @@ -597,27 +597,38 @@ public void setConnectionProperty(String property, Object value) {
}

public ConnectionHolder createConnectionHolder() throws IOException {
// first check if it's cached
// check if it's cached
if (null != cacheEntry) {
if (Logger.canLog(Logger.DEBUG)) {
Logger.logMsg(Logger.DEBUG, "Locator.createConnectionHolder: media cached, creating memory connection holder");
}
return ConnectionHolder.createMemoryConnectionHolder(cacheEntry.getBuffer());
}

// then fall back on other methods
ConnectionHolder holder;
// check if it is local file
if ("file".equals(scheme)) {
holder = ConnectionHolder.createFileConnectionHolder(uri);
} else if (uri.toString().endsWith(".m3u8") || uri.toString().endsWith(".m3u")) {
holder = ConnectionHolder.createHLSConnectionHolder(uri);
} else {
synchronized (propertyLock) {
holder = ConnectionHolder.createURIConnectionHolder(uri, connectionProperties);
}
return ConnectionHolder.createFileConnectionHolder(uri);
}

// check if it is HTTP Live Streaming
// - uri path ends with .m3u8 or .m3u
// - contentType is "application/vnd.apple.mpegurl" or "audio/mpegurl"
String uriPath = uri.getPath();
if (uriPath != null && (uriPath.endsWith(".m3u8") ||
uriPath.endsWith(".m3u"))) {
return ConnectionHolder.createHLSConnectionHolder(uri);
}

return holder;
String type = getContentType(); // Should be ready by now

This comment has been minimized.

Copy link
@CodeDead

CodeDead Sep 17, 2022

This line might produce bugs when creating Media objects from project resources (mp3 file):

Exception in thread "JavaFX Application Thread" MediaException: MEDIA_UNSUPPORTED : Unrecognized file signature!
	at javafx.media@19/javafx.scene.media.Media.<init>(Media.java:411)
	at Opal/com.codedead.opal.domain.SoundPane$1.changed(SoundPane.java:61)
	at Opal/com.codedead.opal.domain.SoundPane$1.changed(SoundPane.java:56)
	at javafx.base@19/com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(ExpressionHelper.java:181)
	at javafx.base@19/com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:80)
	at javafx.base@19/javafx.beans.property.StringPropertyBase.fireValueChangedEvent(StringPropertyBase.java:104)
	at javafx.base@19/javafx.beans.property.StringPropertyBase.markInvalid(StringPropertyBase.java:111)
	at javafx.base@19/javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:145)
	at javafx.base@19/javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:50)
	at javafx.base@19/javafx.beans.property.StringProperty.setValue(StringProperty.java:71)
	at Opal/com.codedead.opal.domain.SoundPane.setMediaPath(SoundPane.java:197)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
	at java.base/java.lang.reflect.Method.invoke(Method.java:577)
	at com.sun.javafx.reflect.Trampoline.invoke(MethodUtil.java:77)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
	at java.base/java.lang.reflect.Method.invoke(Method.java:577)
	at javafx.base@19/com.sun.javafx.reflect.MethodUtil.invoke(MethodUtil.java:275)
	at javafx.fxml@19/com.sun.javafx.fxml.MethodHelper.invoke(MethodHelper.java:84)
	at javafx.fxml@19/com.sun.javafx.fxml.ModuleHelper.invoke(ModuleHelper.java:100)
	at javafx.fxml@19/com.sun.javafx.fxml.BeanAdapter.put(BeanAdapter.java:259)
	at javafx.fxml@19/com.sun.javafx.fxml.BeanAdapter.put(BeanAdapter.java:54)
	at javafx.fxml@19/javafx.fxml.FXMLLoader$Element.applyProperty(FXMLLoader.java:523)
	at javafx.fxml@19/javafx.fxml.FXMLLoader$Element.processValue(FXMLLoader.java:373)
	at javafx.fxml@19/javafx.fxml.FXMLLoader$Element.processPropertyAttribute(FXMLLoader.java:335)
	at javafx.fxml@19/javafx.fxml.FXMLLoader$Element.processInstancePropertyAttributes(FXMLLoader.java:245)
	at javafx.fxml@19/javafx.fxml.FXMLLoader$ValueElement.processEndElement(FXMLLoader.java:778)
	at javafx.fxml@19/javafx.fxml.FXMLLoader.processEndElement(FXMLLoader.java:2924)
	at javafx.fxml@19/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2639)
	at javafx.fxml@19/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2548)
	at javafx.fxml@19/javafx.fxml.FXMLLoader.load(FXMLLoader.java:2516)
	at Opal/com.codedead.opal.OpalApplication.start(OpalApplication.java:102)
	at javafx.graphics@19/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:847)
	at javafx.graphics@19/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:484)
	at javafx.graphics@19/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:457)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
	at javafx.graphics@19/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:456)
	at javafx.graphics@19/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
	at javafx.graphics@19/com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
	at javafx.graphics@19/com.sun.glass.ui.gtk.GtkApplication.lambda$runLoop$11(GtkApplication.java:316)
	at java.base/java.lang.Thread.run(Thread.java:833)

Sample:

package org.example;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.stage.Stage;

import java.net.URISyntaxException;

public class Main extends Application {
    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(final Stage primaryStage) throws URISyntaxException {
        final StackPane root = new StackPane();
        primaryStage.setScene(new Scene(root, 300, 250));
        primaryStage.show();

        final MediaPlayer player1 = new MediaPlayer(new Media(getClass().getResource("/static.mp3").toURI().toString()));
        player1.setAutoPlay(true);
    }
}

MP3:
https://codedead.com/static.mp3 (royalty free)

if (type != null && (type.equals(MediaUtils.CONTENT_TYPE_M3U8) ||
type.equals(MediaUtils.CONTENT_TYPE_M3U))) {
return ConnectionHolder.createHLSConnectionHolder(uri);
}

// media file over http/https
synchronized (propertyLock) {
return ConnectionHolder.createURIConnectionHolder(uri, connectionProperties);
}
}

private String getContentTypeFromFileSignature(URI uri) throws MalformedURLException, IOException {
Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2010, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -158,49 +158,62 @@ else if ((buf[8] & 0xff) == 0x69 && (buf[9] & 0xff) == 0x73 && (buf[10] & 0xff)
contentType = CONTENT_TYPE_MP4;
else if ((buf[8] & 0xff) == 0x4D && (buf[9] & 0xff) == 0x50 && (buf[10] & 0xff) == 0x34 && (buf[11] & 0xff) == 0x20) // 'MP4 '
contentType = CONTENT_TYPE_MP4;
} else if ((buf[0] & 0xff) == 0x23
&& (buf[1] & 0xff) == 0x45
&& (buf[2] & 0xff) == 0x58
&& (buf[3] & 0xff) == 0x54
&& (buf[4] & 0xff) == 0x4d
&& (buf[5] & 0xff) == 0x33
&& (buf[6] & 0xff) == 0x55) { // "#EXTM3U"
contentType = CONTENT_TYPE_M3U8;
} else {
throw new MediaException("Unrecognized file signature!");
}

return contentType;
}

/**
* Returns the content type given the file name.
*
* @param filename
* @return content type
*/
public static String filenameToContentType(String filename) {
String contentType = Locator.DEFAULT_CONTENT_TYPE;
if (filename == null) {
return Locator.DEFAULT_CONTENT_TYPE;
}

int dotIndex = filename.lastIndexOf(".");

if (dotIndex != -1) {
String extension = filename.toLowerCase().substring(dotIndex + 1);

if (extension.equals(FILE_TYPE_AIF) || extension.equals(FILE_TYPE_AIFF)) {
contentType = CONTENT_TYPE_AIFF;
} else if (extension.equals(FILE_TYPE_FLV) || extension.equals(FILE_TYPE_FXM)) {
contentType = CONTENT_TYPE_JFX;
} else if (extension.equals(FILE_TYPE_MPA)) {
contentType = CONTENT_TYPE_MPA;
} else if (extension.equals(FILE_TYPE_WAV)) {
contentType = CONTENT_TYPE_WAV;
} else if (extension.equals(FILE_TYPE_MP4)) {
contentType = CONTENT_TYPE_MP4;
} else if (extension.equals(FILE_TYPE_M4A)) {
contentType = CONTENT_TYPE_M4A;
} else if (extension.equals(FILE_TYPE_M4V)) {
contentType = CONTENT_TYPE_M4V;
} else if (extension.equals(FILE_TYPE_M3U8)) {
contentType = CONTENT_TYPE_M3U8;
} else if (extension.equals(FILE_TYPE_M3U)) {
contentType = CONTENT_TYPE_M3U;
switch (extension) {
case FILE_TYPE_AIF:
case FILE_TYPE_AIFF:
return CONTENT_TYPE_AIFF;
case FILE_TYPE_FLV:
case FILE_TYPE_FXM:
return CONTENT_TYPE_JFX;
case FILE_TYPE_MPA:
return CONTENT_TYPE_MPA;
case FILE_TYPE_WAV:
return CONTENT_TYPE_WAV;
case FILE_TYPE_MP4:
return CONTENT_TYPE_MP4;
case FILE_TYPE_M4A:
return CONTENT_TYPE_M4A;
case FILE_TYPE_M4V:
return CONTENT_TYPE_M4V;
case FILE_TYPE_M3U8:
return CONTENT_TYPE_M3U8;
case FILE_TYPE_M3U:
return CONTENT_TYPE_M3U;
default:
break;
}
}

return contentType;
return Locator.DEFAULT_CONTENT_TYPE;
}

/**
Expand Down

1 comment on commit d1110f4

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.