eshaz / icecast-metadata-js

Browser and NodeJS packages for playing and reading Icecast compatible streaming audio with realtime metadata updates.
155 stars 20 forks source link

Stream never gets buffered state and stream not starting #89

Closed BajakiGabesz closed 2 years ago

BajakiGabesz commented 2 years ago

When starting a stream on mobile devices, it never gets buffered state, and the stream does not start to play. It was working properly in version 1.8.0, but not in 1.9.0 and later. I saw there were some changes around the codec. Do you have any ideas about what causes this issue? If I change the playback method to html5, it looks like it's started but there is no sound. This issue comes up especially on iPhones and some TVs inbuilt browsers, on Android it's working properly.

eshaz commented 2 years ago

Do you have a stream I can test this with so I can reproduce the issue? When you're testing on an iPhone, can you narrow it down to a specific version of iOS where the problem is happening? Can you try out the html demo page with your stream on those devices that are having issues?

BajakiGabesz commented 2 years ago

Thanks for your fast reply! Sure, you can reproduce it with the one I shared with you in the previous issue as well if you try to start the stream on iPhone for example: https://oxygenmusic.hu:8443/oxygenmagyarzene

eshaz commented 2 years ago

It plays fine for me in the html demo page on iOS 14.4. Which version of iOS are you testing with?

BajakiGabesz commented 2 years ago

I am on 14.8 currently. Can you send me the demo page url where you tested it? I will try to compare to my solution, maybe there is a problem in my implementation.

eshaz commented 2 years ago

Here's the demo / test url https://eshaz.github.io/icecast-metadata-js/demo.html

BajakiGabesz commented 2 years ago

Your demo is working fine, sorry for the false alarm. I'll check it on my WebApp side to find out what causes this issue. Please keep this issue open until I find out what is really happening on my side. If I find the workaround, I will write it here to help others as well who may face the same issue. Thanks for putting so much effort into it!

eshaz commented 2 years ago

@BajakiGabesz I fixed a few bugs with the webaudio playback method (which is used in iOS) in #90 . It's possible this may fix your problem. Could you upgrade to icecast-metadata-player/1.10.3 and see if that helps?

BajakiGabesz commented 2 years ago

Thanks for your reply. I checked it and it looks like the stream has been started but there is no sound at all. I will have a debug session tomorrow about this and I try to find out what causes this issue.

BajakiGabesz commented 2 years ago

Sorry to come back just now. I tested with the latest version of icecast-metadata-player 1.10.4 and it looks like it's playing the stream but there's no sound at all. I tested it with the demo that you provided: https://eshaz.github.io/icecast-metadata-js/demo.html It does the same, I tried with our own stream and with 90.9 Jazzy rádió - Jazzy Soul - MP3 and it also doesn't have sound at all but the Last Updated field is continuously updated and the metadata updating well. The last version which worked properly was 1.8.0. Maybe it helps. 1.9.0 starts also the playback, but there is no sound. I am on iPhone 12 and iOS 14.8.1 and I use the latest Chrome browser to test, but I have the same results with Safari. I got a note from some iOS users, it is possible there is no sound on some websites if the Silent mode is switched on. So, I tried toggling between silent and normal mode, but I get the same results as well. Can you check it one more time?

eshaz commented 2 years ago

Could you try checking out this branch and testing this out on your iPhone? The only difference between version 1.8.0 and 1.9.0 is that I changed the web audio decoder library to use a web worker, vs. decoding on the main thread. I put the old main thread decoder back in this branch to see if that's the issue. https://github.com/eshaz/icecast-metadata-js/tree/ios-issues

You can run the demo page locally by cloning this repo, then cd src/demo, run npm i, and npm start. You can then navigate to the demo page from your iPhone by typing in the ip address of your computer in the address bar in Safari (i.e. http://192.168.1.1:3000). Obviously, this will only work if you phone is on the same network as your computer.

Please let me know what you find out. In the meantime, I'm installing a newer version of Xcode that should have an iOS 14.8 simulator. Everything worked great with the iOS 14.4 simulator.

BajakiGabesz commented 2 years ago

I did the test just now. Unfortunately, it behaves the same way as earlier. I did make a build from the 1.8.0 tag as well and it plays perfectly. My experience is that the iOS Simulators sometimes do not behave the same way as the real devices do, but if it helps, I could test it on a Simulator tonight and we will see what is happening. If I remember well, I have a newer version of iOS Simulator because of my macOS version, but it could be relevant maybe. By the way, on macOS, it works properly from the Chrome browser.

BajakiGabesz commented 2 years ago

I tried all the versions one by one and it is working fine until icecast-metadata-player 1.10.2 with mpg123-decoder version 0.3.0 and below. 1.10.3 doesn't give sound at all on my device. I saw there was a change in Player.js and if I understood well, if something goes wrong here we didn't get any notification about the error, just playing silence and that's what exactly happens here I think. On my implementation, the only working version is 1.8.0. I will continue the investigation later today.

eshaz commented 2 years ago

Thanks for checking that. I'm thinking now that there is a problem with the decoded audio not being played. There was an issue with the mpg123-decoder library not working with webpack and other bundlers in icecast-metadata-player 1.9.0 - 1.10.2, which may explain why those versions don't work with your implementation. Are you using a bundle like webpack to build your app? I fixed the mpg123-decoder webpack issue in 1.10.3, but also made a few fixes to the webaudio playback method. I'm going to look there next.

Do you get any errors or any feedback at all in the console output? You will need to connect your iPhone to your debug console on your Mac to see the output.

Also, could you add a break point in the _decodeAndPlay somewhere after the if statement to see if samplesDecoded is returning a positive value? You should be able to do this after connecting your iPhone to the debug console.

eshaz commented 2 years ago

I found the issue! Apparently iOS recently added AudioContext to the window object. Previously, to create an AudioContext in iOS, webkitAudioContext had to be used. This changed essentially caused the Audio Context to never start playing.

I've released icecast-metadata-player/1.10.5 with the updates.

I tested this on an iPhone running iOS 14.8 and it worked perfectly. Could you try the demo page and the new version with your implementation to make sure it works?

BajakiGabesz commented 2 years ago

My implementation and your demo are also working fine now on Safari and I tested it today with Firefox and Opera and those are also fine! I really wanna thank you for all the efforts which you put into it to get the actual state. Unfortunately, Chrome is just showing it's playing the audio but there is no sound. I will try to debug it and I hope I will find something that can help. I know its market share is really small on iOS, but it could be the best solution to be able to use it in that browser as well because maybe this issue is happening to another Chromium-based browser as well and it was also working fine in version 1.8.0 as I always test my pages in Chrome everywhere. I already got news about TVs which do the same thing especially the LG televisions. Maybe it's an error on my side only, but if you can take a look at it and if you can run a test too that I really appreciate it!

eshaz commented 2 years ago

Chrome and any other browser, including Safari, on iOS all use the same webkit browser engine. When you run Chrome on iOS, there's really no difference compared to Safari behind the scenes. I suppose it's possible the user agent logic I added isn't working for iOS Chrome. Opera is a Chromium based browser.

Chrome and Chromium based browsers (i.e. Opera, Edge) on Android, Windows, MacOS, and Linux all work fine for me.

Could you reply with the version(s) of Chrome, which device(s) you're running it on, and the window.navigator.userAgent user agent of the device(s)? You can use the demo page to try different combinations of playback methods to see what works and doesn't work and report back with that information as well.

As far as getting this to work with smart TVs, that's going to be exceedingly difficult and not possible in some cases. Many times smart TV have use limited and/or outdated versions of web browsers. In order for me to look into issues with specific TVs or non standard devices, I will need to have a really good technical understanding of the nature of the problem before I can attempt to fix it.

eshaz commented 2 years ago

@BajakiGabesz, I did find the issue with Chrome on iOS, and it was a problem with the user agent check. The check is not really necessary, it just prevents a deprecation error from showing up for ScriptProcessor, so I removed it. This fixed the issue on iOS Chrome. It's possible it might fix the problem with your TV as well.

Can you try again with icecast-metadata-player/1.10.6?

BajakiGabesz commented 2 years ago

I really want to thank you for all the effort which you put into this solution. Now, everything works fine! I really appreciate your help!

eshaz commented 2 years ago

Excellent to hear. I'm glad to help! Also, thank you for reporting and helping to test these issues. I wouldn't have found them otherwise.

BajakiGabesz commented 2 years ago

Sorry to come back here again. I have finalized the things in my implementation and I made a production build and on iOS I am not able to play the streams. I just debugged it and the console says: ReferenceError: Can't find variable: c This message arrives not much time after I push play on a stream. In the network traffic I see the stream is continuously fetched but nothing happens, it is just stuck into the buffering state. I tried to disable all my event handlers and check it but I got the same result. The packages that you use in the demo are the same as what I use currently. Do you have any idea what could possibly go wrong? I know this error message is not so helpful, I could give you a test URL if you think, but only in PM, because it's not public yet.

eshaz commented 2 years ago

This looks like a minifier issue to me. It could be that your minifier is renaming a variable that is not supposed to be renamed, like a key on an object that is used somewhere that the minifier isn't picking up.

You might be able to run your minifier in debug mode, which usually appends a _ to the full variable name rather than completely minifiying it.

Could you open a new issue for this one if it turns out the variable is originating from this library?

BajakiGabesz commented 2 years ago

Thank you for your help again, it was because of a new webpack version where some plugin was not added. Now, it is working fine!