YouTube iFrame API Not Working Properly In JavaFX

2019-07-24 19:12发布

So recently I've been working on making an audioplayer that can play playlists made by the user (mp3 files, wav files etc.) but that can also play YouTube playlists. In order to play YouTube videos I use JavaFX's WebView in combination with Google's YouTube iFrame API. In order to do so, I use the following code;

    @Override
    public void loadList(String list) 
    {
        html = "<!DOCTYPE html>\n" +
        "<html>\n" +
        "  <body>\n" +
        "<iframe id=\"player\" width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/videoseries?list=PL7aXwAD1wk5kdkuQOFBHY63R9Bhki7rCg&enablejsapi=1\" frameborder=\"0\" gesture=\"media\" allowfullscreen></iframe>\n" +
        "\n" +
        "<script type=\"text/javascript\">\n" +
        "  var tag = document.createElement('script');\n" +
        "  tag.id = 'iframe-demo';\n" +
        "  tag.src = 'https://www.youtube.com/iframe_api';\n" +
        "  var firstScriptTag = document.getElementsByTagName('script')[0];\n" +
        "  var volume = 100;\n" +
        "  firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);\n" +
        "\n" +
        "  var player;\n" +
        "  function onYouTubeIframeAPIReady() {\n" +
        "    player = new YT.Player('player', {\n" +
        "        events: {\n" +
        "          'onReady': onPlayerReady,\n" +
        "          'onError' : handleError,\n" +
        "          'onStateChange' : stateChange,\n" +
        "          'onApiChange' : stateChange\n" +
        "        }\n" +
        "    });\n" +
        "  }\n" +
        "  function onPlayerReady(event) {\n" +
        "     event.target.playVideo();\n" +
        "      //event.target.nextVideo();\n" +
        "  }\n" +
        "    \n" +
        "    function handleError(event)\n" +
        "    {\n" +
        "        console.log(event);\n" +
        "        player.nextVideo();\n" +
        "    }\n" +
        "    \n" +
        "    function setVolume(vol)\n" +
        "    {\n" +
        "        volume = vol;\n" +
        "        player.setVolume(vol);\n" +
        "    }\n" +
        "    \n" +
        "    function stateChange(event)\n" +
        "    {\n" +
        "       // player.setVolume(volume + 1);\n" +
        "       // player.setVolume(volume - 1);\n" +
        "      //  player.setVolume(volume);\n" +
        "    }\n" +
        "</script>\n" +
        "  </body>\n" +
        "</html>";

        jfxPanel = new JFXPanel();
        Platform.runLater ( new Runnable () {
            @Override
            public void run () {
                player = new WebView();

                player.getEngine().setJavaScriptEnabled(true);
                player.getEngine().loadContent(html);
                jfxPanel.setScene(new Scene(player));
                JFrame f = new JFrame();
                f.add(jfxPanel);
                f.setSize(1280,720);
                f.setVisible(true);

            }
        } );
        GraphicalInterface.uptodate = false;
    }

The issue I am having is this: Once I use the API's 'player.setVolume(vol)' functionality, it correctly changes the volume for the video it is currently playing. When a new video loads, the videoplayer still shows the volume is the same as it had previously been set to, but it outputs too high of a volume; first video, lowered volume; enter image description here

second video, volumeslider is lowered, volume itself isn't; enter image description here

I only have this issue when using JavaFX's WebView. When I paste the HTML code in a .html file and run it that way, the audio is correctly lowered (and not just the audio slider).

Does anyone know why this could be happening and how I can fix this? Does it have to do with the WebView's settings?

Note: In the JavaScript I have commented out a small piece of code. This code is a small temporary workaround that "re-setd" the audio to where it should be when a new video is loaded. This solution is not ideal though.

0条回答
登录 后发表回答