Compare commits

..

4 Commits
v1.4 ... v1.4.1

Author SHA1 Message Date
7207646379 Bump version to 1.4.1 2023-07-21 09:02:37 +07:00
597c150c77 Update README.md 2023-07-21 09:02:10 +07:00
e7980c186d Add Kiwi Browser support (#11)
* Catch exception when trying to force desktop codec profile on Kiwi Browser

* Improve setCodecPreferences(), avoid crashing

* Improve codec status detection

* Fix codec detection
2023-07-21 08:57:05 +07:00
0c38b54c38 Update README.md 2023-07-20 21:06:49 +07:00
2 changed files with 68 additions and 26 deletions

View File

@ -17,12 +17,13 @@ Give this project a 🌟 if you like it. Thank you 🙏.
> By default you only get 1080p stream when playing on desktop. > By default you only get 1080p stream when playing on desktop.
> This feature will give you 1080p stream even on mobile, without having to change User-Agent. > This feature will give you 1080p stream even on mobile, without having to change User-Agent.
> Not working in Hermit ([#5](https://github.com/redphx/better-xcloud/issues/5)). > Not working in Hermit ([#5](https://github.com/redphx/better-xcloud/issues/5)).
- **Force high quality codec <sup>(\*)</sup>** - **Force high quality codec (if possible)<sup>(\*)</sup>**
> Force xCloud to use the best streaming codec profile (same as desktop & TV). You don't have to change User-Agent anymore. > Force xCloud to use the best streaming codec profile (same as desktop & TV) if possible. You don't have to change User-Agent anymore.
> You should enable this feature even if you're on desktop. > You should enable this feature even if you're on desktop.
> Use more bandwidth & battery. > Use more bandwidth & battery.
> Comparison video with the setting ON & OFF: https://youtu.be/-9PuBJJSgR4 > Comparison video with the setting ON & OFF: https://youtu.be/-9PuBJJSgR4
> Disable if it causes crashes. > Disable if it causes crashes.
> This feature doesn't work on Kiwi Browser (unsupported codec).
- **Prefer IPv6 streaming server** - **Prefer IPv6 streaming server**
> Might reduce latency > Might reduce latency
- **Disable bandwidth checking** - **Disable bandwidth checking**
@ -64,19 +65,22 @@ To update manually, just install the script again (you won't lose your settings)
✅ = confirmed to be working ✅ = confirmed to be working
❓ = not yet tested ❓ = not yet tested
❌ = not supported (mostly because of lacking Userscript/extension support) ❌ = not supported (mostly because of lacking Userscript/extension support)
= unavailable
⚠️ = see custom notes ⚠️ = see custom notes
| | Desktop | Android | iOS | | | Desktop | Android | iOS |
|----------------------------------------|------------------|------------------|-----------------| |----------------------------------------|------------------|------------------|------------------|
| Chrome/Edge/Chromium variants | ✅ | ❌ | ❌ | | Chrome/Edge/Chromium variants | ✅ | ❌ | ❌ |
| Firefox | ✅ | ✅ | ❌ | | Firefox | ✅ | ✅<sup>(1)</sup> | ❌ |
| Safari | ✅<sup>(1)</sup> | | ✅<sup>(2)</sup> | | Safari | ✅<sup>(2)</sup> | | ✅<sup>(3)</sup> |
| [Hermit](https://hermit.chimbori.com) | | ⚠️<sup>(3)</sup> | | | [Hermit](https://hermit.chimbori.com) | | ⚠️<sup>(4)</sup> | |
| Kiwi Browser | | ✅<sup>(5)</sup> | |
Don't see your browser in the table? If it supports Tampermonkey/Userscript then the answer is likely **"YES"**. Don't see your browser in the table? If it supports Tampermonkey/Userscript then the answer is likely **"YES"**.
<sup>1, 2</sup> Requires [Userscripts app](https://apps.apple.com/us/app/userscripts/id1463298887) (free & open source). <sup>1</sup> Follow [this guide](https://support.mozilla.org/en-US/kb/find-and-install-add-ons-firefox-android) to install Tampermonkey on Firefox Android.
<sup>3</sup> NOT RECOMMENDED at the moment since its Userscript implementation is not working properly (see https://github.com/redphx/better-xcloud/issues/5 for full details). It's still my favorite app to play xCloud on because it's lightweight, supports Userscript (premium features, only $1.99) without having to install anything else. I built **Better xCloud** just so I could use it with Hermit. <sup>2, 3</sup> Requires [Userscripts app](https://apps.apple.com/us/app/userscripts/id1463298887) (free & open source).
<sup>4</sup> NOT RECOMMENDED at the moment since its Userscript implementation is not working properly (see https://github.com/redphx/better-xcloud/issues/5 for full details). It's still my favorite app to play xCloud on because it's lightweight, supports Userscript (premium features, only $1.99) without having to install anything else. I built **Better xCloud** just so I could use it with Hermit.
<sup>5</sup> The "Force high quality codec" is unsupported (causes crashes).
## FAQ ## FAQ
1. **Will I get banned for using this?** 1. **Will I get banned for using this?**
I think it's very unlikely that you'll get banned for using this. Most of the features only affect client-side, except for switching region of streaming server (you'll connect to another server instead of the default one). If you want to be safe just avoid using that. As always, use as your own risk. I think it's very unlikely that you'll get banned for using this. Most of the features only affect client-side, except for switching region of streaming server (you'll connect to another server instead of the default one). If you want to be safe just avoid using that. As always, use as your own risk.

View File

@ -1,7 +1,7 @@
// ==UserScript== // ==UserScript==
// @name Better xCloud // @name Better xCloud
// @namespace https://github.com/redphx // @namespace https://github.com/redphx
// @version 1.4 // @version 1.4.1
// @description Improve Xbox Cloud Gaming (xCloud) experience // @description Improve Xbox Cloud Gaming (xCloud) experience
// @author redphx // @author redphx
// @license MIT // @license MIT
@ -13,7 +13,7 @@
// ==/UserScript== // ==/UserScript==
'use strict'; 'use strict';
const SCRIPT_VERSION = '1.4'; const SCRIPT_VERSION = '1.4.1';
const SCRIPT_HOME = 'https://github.com/redphx/better-xcloud'; const SCRIPT_HOME = 'https://github.com/redphx/better-xcloud';
const SERVER_REGIONS = {}; const SERVER_REGIONS = {};
@ -83,7 +83,7 @@ class Preferences {
{ {
'id': Preferences.USE_DESKTOP_CODEC, 'id': Preferences.USE_DESKTOP_CODEC,
'label': 'Force high quality codec', 'label': 'Force high quality codec (if possible)',
'default': false, 'default': false,
}, },
@ -1021,19 +1021,37 @@ function patchRtcCodecs() {
RTCRtpTransceiver.prototype.orgSetCodecPreferences = RTCRtpTransceiver.prototype.setCodecPreferences; RTCRtpTransceiver.prototype.orgSetCodecPreferences = RTCRtpTransceiver.prototype.setCodecPreferences;
RTCRtpTransceiver.prototype.setCodecPreferences = function(codecs) { RTCRtpTransceiver.prototype.setCodecPreferences = function(codecs) {
// Use the same codecs as desktop // Use the same codecs as desktop
codecs = [ let profileSetting;
{ for (let codec of codecs) {
'clockRate': 90000, if (codec.sdpFmtpLine.includes('profile-level-id=4d') || codec.sdpFmtpLine.includes('profile-level-id=42')) {
'mimeType': 'video/H264', profileSetting = codec.sdpFmtpLine.slice(-4); // get the last 4 characters
'sdpFmtpLine': 'level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=4d001f', break;
},
{
'clockRate': 90000,
'mimeType': 'video/H264',
'sdpFmtpLine': 'level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=4d001f',
} }
].concat(codecs); }
this.orgSetCodecPreferences(codecs);
let newCodecs;
if (profileSetting) {
newCodecs = [
{
'clockRate': 90000,
'mimeType': 'video/H264',
'sdpFmtpLine': 'level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=4d' + profileSetting,
},
{
'clockRate': 90000,
'mimeType': 'video/H264',
'sdpFmtpLine': 'level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=4d' + profileSetting,
}
].concat(codecs);
} else {
newCodecs = codecs;
}
try {
this.orgSetCodecPreferences(newCodecs);
} catch (e) {
this.orgSetCodecPreferences(codecs);
}
} }
} }
@ -1275,10 +1293,30 @@ if (document.readyState === 'complete' && !onLoadTriggered) {
RTCPeerConnection.prototype.orgSetRemoteDescription = RTCPeerConnection.prototype.setRemoteDescription; RTCPeerConnection.prototype.orgSetRemoteDescription = RTCPeerConnection.prototype.setRemoteDescription;
RTCPeerConnection.prototype.setRemoteDescription = function(...args) { RTCPeerConnection.prototype.setRemoteDescription = function(...args) {
StreamStatus.hqCodec = false;
const sdpDesc = args[0]; const sdpDesc = args[0];
if (sdpDesc.sdp) { if (sdpDesc.sdp) {
StreamStatus.hqCodec = sdpDesc.sdp.includes('profile-level-id=4d'); const sdp = sdpDesc.sdp;
let lineIndex = 0;
let endPos = 0;
let line;
while (lineIndex > -1) {
lineIndex = sdp.indexOf('a=fmtp:', endPos);
if (lineIndex === -1) {
break;
}
endPos = sdp.indexOf('\n', lineIndex);
line = sdp.substring(lineIndex, endPos);
if (line.includes('profile-level-id')) {
StreamStatus.hqCodec = line.includes('profile-level-id=4d');
break;
}
}
} }
return this.orgSetRemoteDescription.apply(this, args); return this.orgSetRemoteDescription.apply(this, args);
} }