Compare commits

..

39 Commits

Author SHA1 Message Date
semantic-release-bot
899121b9de chore: Release v5.7.1-dev.3 [skip ci]
## [5.7.1-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.7.1-dev.2...v5.7.1-dev.3) (2024-12-22)

### Bug Fixes

* **YouTube - SponsorBlock:** Show a toast and not a dialog if segment submitted successfully ([838edb4](838edb48e7))
2024-12-22 17:34:19 +00:00
LisoUseInAIKyrios
838edb48e7 fix(YouTube - SponsorBlock): Show a toast and not a dialog if segment submitted successfully 2024-12-22 21:31:41 +04:00
semantic-release-bot
b2665c916a chore: Release v5.7.1-dev.2 [skip ci]
## [5.7.1-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.7.1-dev.1...v5.7.1-dev.2) (2024-12-22)

### Bug Fixes

* **YouTube - Theme:** Use dark theme color for status and navigation bar ([4b81f70](4b81f7009b))
2024-12-22 11:29:57 +00:00
LisoUseInAIKyrios
4b81f7009b fix(YouTube - Theme): Use dark theme color for status and navigation bar 2024-12-22 15:27:02 +04:00
semantic-release-bot
1a4c39a2ee chore: Release v5.7.1-dev.1 [skip ci]
## [5.7.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.7.0...v5.7.1-dev.1) (2024-12-22)

### Bug Fixes

* **YouTube - Spoof video streams:** Use Android VR authentication if using default audio language ([#4191](https://github.com/ReVanced/revanced-patches/issues/4191)) ([99334d1](99334d1e53))
2024-12-22 10:26:04 +00:00
LisoUseInAIKyrios
99334d1e53 fix(YouTube - Spoof video streams): Use Android VR authentication if using default audio language (#4191) 2024-12-22 14:22:49 +04:00
semantic-release-bot
2850a6ed4e chore: Release v5.7.0 [skip ci]
# [5.7.0](https://github.com/ReVanced/revanced-patches/compare/v5.6.0...v5.7.0) (2024-12-22)

### Bug Fixes

* **YouTube - Force original audio:** Use correct availability for settings UI ([a0b63df](a0b63dfa23))
* **YouTube - Spoof video stream:** Remove UI client type setting.  Allow setting default audio language. ([#4184](https://github.com/ReVanced/revanced-patches/issues/4184)) ([aeedec7](aeedec7fed))
* **YouTube - Spoof video streams:** Remove iOS, add clients Android TV and Android Creator ([#4180](https://github.com/ReVanced/revanced-patches/issues/4180)) ([cdb6820](cdb68209d1))
* **YouTube:** Change fingerprints to support a wider range of target versions ([25d7cc6](25d7cc68ae))

### Features

* **YouTube:** Support version `19.47.53` ([#4182](https://github.com/ReVanced/revanced-patches/issues/4182)) ([b8635d0](b8635d0b88))
2024-12-22 07:53:45 +00:00
LisoUseInAIKyrios
f28eb5105b chore: Merge branch dev to main (#4188) 2024-12-22 11:50:32 +04:00
github-actions[bot]
69bed4d9fa chore: Sync translations (#4187) 2024-12-22 11:49:37 +04:00
oSumAtrIX
a5f1efac27 chore: Merge branch dev to main (#4183) 2024-12-22 08:48:36 +01:00
semantic-release-bot
b51be82cff chore: Release v5.7.0-dev.1 [skip ci]
# [5.7.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.6.1-dev.4...v5.7.0-dev.1) (2024-12-21)

### Features

* **YouTube:** Support version `19.47.53` ([#4182](https://github.com/ReVanced/revanced-patches/issues/4182)) ([b8635d0](b8635d0b88))
2024-12-21 15:09:41 +00:00
LisoUseInAIKyrios
b8635d0b88 feat(YouTube): Support version 19.47.53 (#4182) 2024-12-21 19:06:51 +04:00
semantic-release-bot
78699c8bbf chore: Release v5.6.1-dev.4 [skip ci]
## [5.6.1-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.6.1-dev.3...v5.6.1-dev.4) (2024-12-21)

### Bug Fixes

* **YouTube - Spoof video stream:** Remove UI client type setting.  Allow setting default audio language. ([#4184](https://github.com/ReVanced/revanced-patches/issues/4184)) ([aeedec7](aeedec7fed))
2024-12-21 14:53:47 +00:00
LisoUseInAIKyrios
aeedec7fed fix(YouTube - Spoof video stream): Remove UI client type setting. Allow setting default audio language. (#4184) 2024-12-21 18:49:56 +04:00
semantic-release-bot
32b614696b chore: Release v5.6.1-dev.3 [skip ci]
## [5.6.1-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.6.1-dev.2...v5.6.1-dev.3) (2024-12-21)

### Bug Fixes

* **YouTube - Force original audio:** Use correct availability for settings UI ([a0b63df](a0b63dfa23))
2024-12-21 12:11:12 +00:00
LisoUseInAIKyrios
a0b63dfa23 fix(YouTube - Force original audio): Use correct availability for settings UI 2024-12-21 16:08:22 +04:00
semantic-release-bot
f0f53cf72f chore: Release v5.6.1-dev.2 [skip ci]
## [5.6.1-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.6.1-dev.1...v5.6.1-dev.2) (2024-12-21)

### Bug Fixes

* **YouTube - Spoof video streams:** Remove iOS, add clients Android TV and Android Creator ([#4180](https://github.com/ReVanced/revanced-patches/issues/4180)) ([cdb6820](cdb68209d1))
2024-12-21 11:37:01 +00:00
LisoUseInAIKyrios
cdb68209d1 fix(YouTube - Spoof video streams): Remove iOS, add clients Android TV and Android Creator (#4180) 2024-12-21 15:33:43 +04:00
semantic-release-bot
7369f7b8d5 chore: Release v5.6.1-dev.1 [skip ci]
## [5.6.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.6.0...v5.6.1-dev.1) (2024-12-21)

### Bug Fixes

* **YouTube:** Change fingerprints to support a wider range of target versions ([25d7cc6](25d7cc68ae))
2024-12-21 10:44:05 +00:00
LisoUseInAIKyrios
db521b940b refactor(YouTube): Change fingerprints to support a wider range of target versions (#4179) 2024-12-21 14:41:22 +04:00
LisoUseInAIKyrios
25d7cc68ae fix(YouTube): Change fingerprints to support a wider range of target versions 2024-12-21 12:55:18 +04:00
semantic-release-bot
9495064e6e chore: Release v5.6.0 [skip ci]
# [5.6.0](https://github.com/ReVanced/revanced-patches/compare/v5.5.1...v5.6.0) (2024-12-20)

### Bug Fixes

* **Twitter - Change link sharing domain:** Use correct extension package ([20a7ad4](20a7ad4715))
* **YouTube - Force original audio:** Use correct original audio stream if app language is not English ([1d0ec98](1d0ec98bec))
* **YouTube - Hide layout components:** Hide new kind of community post ([#4155](https://github.com/ReVanced/revanced-patches/issues/4155)) ([246333f](246333f3dc))
* **YouTube - Miniplayer:** Use estimated maximum on screen size for devices with low density screens ([#4150](https://github.com/ReVanced/revanced-patches/issues/4150)) ([c87c788](c87c788a26))
* **YouTube - Open Shorts in regular player:** Do not show the miniplayer after opening a Short while a video is playing ([c7f42d9](c7f42d9a3c))
* **YouTube - SponsorBlock:** Show create new segment error messages using a dialog ([#4148](https://github.com/ReVanced/revanced-patches/issues/4148)) ([44995a9](44995a9f15))
* **YouTube - Spoof video streams:** Change default spoofing to iOS, allow setting a default language with Android VR ([#4171](https://github.com/ReVanced/revanced-patches/issues/4171)) ([cd08717](cd08717783))
* **YouTube - Spoof video streams:** Update iOS client version ([ec746cb](ec746cb05a))

### Features

* **YouTube:** Add `Open Shorts in regular player` patch ([#4153](https://github.com/ReVanced/revanced-patches/issues/4153)) ([1dde485](1dde485013))
2024-12-20 21:57:47 +00:00
LisoUseInAIKyrios
64864c2cdb chore: Merge branch dev to main (#4147) 2024-12-21 01:54:28 +04:00
github-actions[bot]
ad0ffb3328 chore: Sync translations (#4173) 2024-12-21 01:48:25 +04:00
semantic-release-bot
06800324aa chore: Release v5.6.0-dev.6 [skip ci]
# [5.6.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v5.6.0-dev.5...v5.6.0-dev.6) (2024-12-20)

### Bug Fixes

* **YouTube - Spoof video streams:** Update iOS client version ([ec746cb](ec746cb05a))
2024-12-20 21:38:18 +00:00
LisoUseInAIKyrios
ec746cb05a fix(YouTube - Spoof video streams): Update iOS client version 2024-12-21 01:35:06 +04:00
semantic-release-bot
67c5530ea6 chore: Release v5.6.0-dev.5 [skip ci]
# [5.6.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v5.6.0-dev.4...v5.6.0-dev.5) (2024-12-20)

### Bug Fixes

* **YouTube - Spoof video streams:** Change default spoofing to iOS, allow setting a default language with Android VR ([#4171](https://github.com/ReVanced/revanced-patches/issues/4171)) ([cd08717](cd08717783))
2024-12-20 20:41:10 +00:00
LisoUseInAIKyrios
cd08717783 fix(YouTube - Spoof video streams): Change default spoofing to iOS, allow setting a default language with Android VR (#4171) 2024-12-21 00:38:11 +04:00
semantic-release-bot
7bac023ea5 chore: Release v5.6.0-dev.4 [skip ci]
# [5.6.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.6.0-dev.3...v5.6.0-dev.4) (2024-12-20)

### Bug Fixes

* **YouTube - Force original audio:** Use correct original audio stream if app language is not English ([1d0ec98](1d0ec98bec))
2024-12-20 16:29:05 +00:00
LisoUseInAIKyrios
1d0ec98bec fix(YouTube - Force original audio): Use correct original audio stream if app language is not English 2024-12-20 20:26:17 +04:00
semantic-release-bot
3c603fac2d chore: Release v5.6.0-dev.3 [skip ci]
# [5.6.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.6.0-dev.2...v5.6.0-dev.3) (2024-12-20)

### Bug Fixes

* **Twitter - Change link sharing domain:** Use correct extension package ([20a7ad4](20a7ad4715))
2024-12-20 07:16:17 +00:00
LisoUseInAIKyrios
20a7ad4715 fix(Twitter - Change link sharing domain): Use correct extension package 2024-12-20 11:12:50 +04:00
semantic-release-bot
25a60e305e chore: Release v5.6.0-dev.2 [skip ci]
# [5.6.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.6.0-dev.1...v5.6.0-dev.2) (2024-12-19)

### Bug Fixes

* **YouTube - Open Shorts in regular player:** Do not show the miniplayer after opening a Short while a video is playing ([c7f42d9](c7f42d9a3c))
2024-12-19 11:20:50 +00:00
LisoUseInAIKyrios
c7f42d9a3c fix(YouTube - Open Shorts in regular player): Do not show the miniplayer after opening a Short while a video is playing 2024-12-19 15:18:18 +04:00
github-actions[bot]
670f100a29 chore: Sync translations (#4166) 2024-12-19 15:17:50 +04:00
semantic-release-bot
19140e5918 chore: Release v5.6.0-dev.1 [skip ci]
# [5.6.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.5.2-dev.2...v5.6.0-dev.1) (2024-12-19)

### Features

* **YouTube:** Add `Open Shorts in regular player` patch ([#4153](https://github.com/ReVanced/revanced-patches/issues/4153)) ([1dde485](1dde485013))
2024-12-19 08:14:57 +00:00
LisoUseInAIKyrios
1dde485013 feat(YouTube): Add Open Shorts in regular player patch (#4153) 2024-12-19 12:11:19 +04:00
LisoUseInAIKyrios
5efcdd31c8 ci: Don't upload strings to Crowdin when pulling (#4164) 2024-12-18 19:04:09 +01:00
github-actions[bot]
e6529837cb chore: Sync translations (#4162) 2024-12-18 16:29:33 +04:00
166 changed files with 1834 additions and 1412 deletions

View File

@@ -23,6 +23,7 @@ jobs:
uses: crowdin/github-action@v2
with:
config: crowdin.yml
upload_sources: false
download_translations: true
localization_branch_name: feat/translations
create_pull_request: false
@@ -39,4 +40,3 @@ jobs:
destination_branch: dev
pr_title: "chore: Sync translations"
pr_body: "Sync translations from [crowdin.com/project/revanced](https://crowdin.com/project/revanced)"
pr_draft: true

View File

@@ -1,3 +1,135 @@
## [5.7.1-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.7.1-dev.2...v5.7.1-dev.3) (2024-12-22)
### Bug Fixes
* **YouTube - SponsorBlock:** Show a toast and not a dialog if segment submitted successfully ([134b189](https://github.com/ReVanced/revanced-patches/commit/134b189791113dcf1a1cb7c87b8a0954f432730c))
## [5.7.1-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.7.1-dev.1...v5.7.1-dev.2) (2024-12-22)
### Bug Fixes
* **YouTube - Theme:** Use dark theme color for status and navigation bar ([0240efe](https://github.com/ReVanced/revanced-patches/commit/0240efe33e5444625ca2b760c861c9046d3dc836))
## [5.7.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.7.0...v5.7.1-dev.1) (2024-12-22)
### Bug Fixes
* **YouTube - Spoof video streams:** Use Android VR authentication if using default audio language ([#4191](https://github.com/ReVanced/revanced-patches/issues/4191)) ([98773cc](https://github.com/ReVanced/revanced-patches/commit/98773cc7d46e5c9c7715b82c8006f1ccbcc5443c))
# [5.7.0](https://github.com/ReVanced/revanced-patches/compare/v5.6.0...v5.7.0) (2024-12-22)
### Bug Fixes
* **YouTube - Force original audio:** Use correct availability for settings UI ([a7eedcb](https://github.com/ReVanced/revanced-patches/commit/a7eedcb4cca6b7b12629c478c24c0899c80e3615))
* **YouTube - Spoof video stream:** Remove UI client type setting. Allow setting default audio language. ([#4184](https://github.com/ReVanced/revanced-patches/issues/4184)) ([99f3f29](https://github.com/ReVanced/revanced-patches/commit/99f3f29c649bf7693c05bbce2bb49bd53e05f050))
* **YouTube - Spoof video streams:** Remove iOS, add clients Android TV and Android Creator ([#4180](https://github.com/ReVanced/revanced-patches/issues/4180)) ([86abfb2](https://github.com/ReVanced/revanced-patches/commit/86abfb2b0d4675f0a1cb9ab244783075bfe89281))
* **YouTube:** Change fingerprints to support a wider range of target versions ([8a09174](https://github.com/ReVanced/revanced-patches/commit/8a09174def205a26ce49cb7815097e235069526a))
### Features
* **YouTube:** Support version `19.47.53` ([#4182](https://github.com/ReVanced/revanced-patches/issues/4182)) ([2089e61](https://github.com/ReVanced/revanced-patches/commit/2089e613d36c45352db7d852aaee0087b1c3e1a4))
# [5.7.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.6.1-dev.4...v5.7.0-dev.1) (2024-12-21)
### Features
* **YouTube:** Support version `19.47.53` ([#4182](https://github.com/ReVanced/revanced-patches/issues/4182)) ([2089e61](https://github.com/ReVanced/revanced-patches/commit/2089e613d36c45352db7d852aaee0087b1c3e1a4))
## [5.6.1-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.6.1-dev.3...v5.6.1-dev.4) (2024-12-21)
### Bug Fixes
* **YouTube - Spoof video stream:** Remove UI client type setting. Allow setting default audio language. ([#4184](https://github.com/ReVanced/revanced-patches/issues/4184)) ([99f3f29](https://github.com/ReVanced/revanced-patches/commit/99f3f29c649bf7693c05bbce2bb49bd53e05f050))
## [5.6.1-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.6.1-dev.2...v5.6.1-dev.3) (2024-12-21)
### Bug Fixes
* **YouTube - Force original audio:** Use correct availability for settings UI ([a7eedcb](https://github.com/ReVanced/revanced-patches/commit/a7eedcb4cca6b7b12629c478c24c0899c80e3615))
## [5.6.1-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.6.1-dev.1...v5.6.1-dev.2) (2024-12-21)
### Bug Fixes
* **YouTube - Spoof video streams:** Remove iOS, add clients Android TV and Android Creator ([#4180](https://github.com/ReVanced/revanced-patches/issues/4180)) ([86abfb2](https://github.com/ReVanced/revanced-patches/commit/86abfb2b0d4675f0a1cb9ab244783075bfe89281))
## [5.6.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.6.0...v5.6.1-dev.1) (2024-12-21)
### Bug Fixes
* **YouTube:** Change fingerprints to support a wider range of target versions ([8a09174](https://github.com/ReVanced/revanced-patches/commit/8a09174def205a26ce49cb7815097e235069526a))
# [5.6.0](https://github.com/ReVanced/revanced-patches/compare/v5.5.1...v5.6.0) (2024-12-20)
### Bug Fixes
* **Twitter - Change link sharing domain:** Use correct extension package ([ad7fab6](https://github.com/ReVanced/revanced-patches/commit/ad7fab67319ba23f267d27da9b74266965fc4be3))
* **YouTube - Force original audio:** Use correct original audio stream if app language is not English ([0d20171](https://github.com/ReVanced/revanced-patches/commit/0d2017133efac230887b5c2a331d87159df8af11))
* **YouTube - Hide layout components:** Hide new kind of community post ([#4155](https://github.com/ReVanced/revanced-patches/issues/4155)) ([08f68cb](https://github.com/ReVanced/revanced-patches/commit/08f68cb5d33f2cfe656d2f93d159c69981f31418))
* **YouTube - Miniplayer:** Use estimated maximum on screen size for devices with low density screens ([#4150](https://github.com/ReVanced/revanced-patches/issues/4150)) ([2694158](https://github.com/ReVanced/revanced-patches/commit/2694158c3c9935ede21c96832533222f850068df))
* **YouTube - Open Shorts in regular player:** Do not show the miniplayer after opening a Short while a video is playing ([894e366](https://github.com/ReVanced/revanced-patches/commit/894e36665d17d5a3a5728961d424dffc55faa50b))
* **YouTube - SponsorBlock:** Show create new segment error messages using a dialog ([#4148](https://github.com/ReVanced/revanced-patches/issues/4148)) ([5870906](https://github.com/ReVanced/revanced-patches/commit/587090636dfff0b358b15026cf7d47c65a4296dc))
* **YouTube - Spoof video streams:** Change default spoofing to iOS, allow setting a default language with Android VR ([#4171](https://github.com/ReVanced/revanced-patches/issues/4171)) ([171b4e7](https://github.com/ReVanced/revanced-patches/commit/171b4e7e40066e38fba773b7a6525e9a038779ef))
* **YouTube - Spoof video streams:** Update iOS client version ([df3aeed](https://github.com/ReVanced/revanced-patches/commit/df3aeed3b173e408fad80197a89ec5d003a2b328))
### Features
* **YouTube:** Add `Open Shorts in regular player` patch ([#4153](https://github.com/ReVanced/revanced-patches/issues/4153)) ([c7c5e5b](https://github.com/ReVanced/revanced-patches/commit/c7c5e5b2b9cf63d8225bb6bd5e735ddf945b6c29))
# [5.6.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v5.6.0-dev.5...v5.6.0-dev.6) (2024-12-20)
### Bug Fixes
* **YouTube - Spoof video streams:** Update iOS client version ([df3aeed](https://github.com/ReVanced/revanced-patches/commit/df3aeed3b173e408fad80197a89ec5d003a2b328))
# [5.6.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v5.6.0-dev.4...v5.6.0-dev.5) (2024-12-20)
### Bug Fixes
* **YouTube - Spoof video streams:** Change default spoofing to iOS, allow setting a default language with Android VR ([#4171](https://github.com/ReVanced/revanced-patches/issues/4171)) ([171b4e7](https://github.com/ReVanced/revanced-patches/commit/171b4e7e40066e38fba773b7a6525e9a038779ef))
# [5.6.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.6.0-dev.3...v5.6.0-dev.4) (2024-12-20)
### Bug Fixes
* **YouTube - Force original audio:** Use correct original audio stream if app language is not English ([0d20171](https://github.com/ReVanced/revanced-patches/commit/0d2017133efac230887b5c2a331d87159df8af11))
# [5.6.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.6.0-dev.2...v5.6.0-dev.3) (2024-12-20)
### Bug Fixes
* **Twitter - Change link sharing domain:** Use correct extension package ([ad7fab6](https://github.com/ReVanced/revanced-patches/commit/ad7fab67319ba23f267d27da9b74266965fc4be3))
# [5.6.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.6.0-dev.1...v5.6.0-dev.2) (2024-12-19)
### Bug Fixes
* **YouTube - Open Shorts in regular player:** Do not show the miniplayer after opening a Short while a video is playing ([894e366](https://github.com/ReVanced/revanced-patches/commit/894e36665d17d5a3a5728961d424dffc55faa50b))
# [5.6.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.5.2-dev.2...v5.6.0-dev.1) (2024-12-19)
### Features
* **YouTube:** Add `Open Shorts in regular player` patch ([#4153](https://github.com/ReVanced/revanced-patches/issues/4153)) ([c7c5e5b](https://github.com/ReVanced/revanced-patches/commit/c7c5e5b2b9cf63d8225bb6bd5e735ddf945b6c29))
## [5.5.2-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.5.2-dev.1...v5.5.2-dev.2) (2024-12-17)

View File

@@ -3,10 +3,8 @@ package app.revanced.extension.shared.settings;
import static java.lang.Boolean.FALSE;
import static java.lang.Boolean.TRUE;
import static app.revanced.extension.shared.settings.Setting.parent;
import static app.revanced.extension.shared.spoof.SpoofVideoStreamsPatch.SpoofiOSAvailability;
import app.revanced.extension.shared.spoof.AudioStreamLanguage;
import app.revanced.extension.shared.spoof.ClientType;
/**
* Settings shared across multiple apps.
@@ -22,9 +20,5 @@ public class BaseSettings {
public static final IntegerSetting CHECK_ENVIRONMENT_WARNINGS_ISSUED = new IntegerSetting("revanced_check_environment_warnings_issued", 0, true, false);
public static final BooleanSetting SPOOF_VIDEO_STREAMS = new BooleanSetting("revanced_spoof_video_streams", TRUE, true, "revanced_spoof_video_streams_user_dialog_message");
public static final EnumSetting<AudioStreamLanguage> SPOOF_VIDEO_STREAMS_LANGUAGE = new EnumSetting<>("revanced_spoof_video_streams_language", AudioStreamLanguage.DEFAULT, new SpoofiOSAvailability());
public static final BooleanSetting SPOOF_VIDEO_STREAMS_IOS_FORCE_AVC = new BooleanSetting("revanced_spoof_video_streams_ios_force_avc", FALSE, true,
"revanced_spoof_video_streams_ios_force_avc_user_dialog_message", new SpoofiOSAvailability());
public static final EnumSetting<ClientType> SPOOF_VIDEO_STREAMS_CLIENT_TYPE = new EnumSetting<>("revanced_spoof_video_streams_client", ClientType.ANDROID_VR, true, parent(SPOOF_VIDEO_STREAMS));
public static final EnumSetting<AudioStreamLanguage> SPOOF_VIDEO_STREAMS_LANGUAGE = new EnumSetting<>("revanced_spoof_video_streams_language", AudioStreamLanguage.DEFAULT, parent(SPOOF_VIDEO_STREAMS));
}

View File

@@ -4,48 +4,36 @@ import android.os.Build;
import androidx.annotation.Nullable;
import app.revanced.extension.shared.settings.BaseSettings;
public enum ClientType {
// Specific purpose for age restricted, or private videos, because the iOS client is not logged in.
// https://dumps.tadiphone.dev/dumps/oculus/eureka
ANDROID_VR(28,
ANDROID_VR_NO_AUTH( // Must be first so a default audio language can be set.
28,
"ANDROID_VR",
"Quest 3",
"12",
"com.google.android.apps.youtube.vr.oculus/1.56.21 (Linux; U; Android 12; GB) gzip",
"32", // Android 12.1
"1.56.21",
true,
false),
// Specific for kids videos.
IOS(5,
"IOS",
forceAVC()
? "iPhone12,5" // 11 Pro Max (last device with iOS 13)
: "iPhone16,2", // 15 Pro Max
// iOS 13 and earlier uses only AVC. 14+ adds VP9 and AV1.
forceAVC()
? "13.7.17H35" // Last release of iOS 13.
: "17.5.1.21F90",
forceAVC()
? "com.google.ios.youtube/17.40.5 (iPhone; U; CPU iOS 13_7 like Mac OS X)"
: "com.google.ios.youtube/19.47.7 (iPhone; U; CPU iOS 17_5_1 like Mac OS X)",
null,
// Version number should be a valid iOS release.
// https://www.ipa4fun.com/history/185230
forceAVC()
// Some newer versions can also force AVC,
// but 17.40 is the last version that supports iOS 13.
? "17.40.5"
: "19.47.7",
false,
true
);
private static boolean forceAVC() {
return BaseSettings.SPOOF_VIDEO_STREAMS_IOS_FORCE_AVC.get();
}
// Fall over to authenticated ('hl' is ignored and audio is same as language set in users Google account).
ANDROID_VR(
ANDROID_VR_NO_AUTH.id,
ANDROID_VR_NO_AUTH.clientName,
ANDROID_VR_NO_AUTH.deviceModel,
ANDROID_VR_NO_AUTH.osVersion,
ANDROID_VR_NO_AUTH.userAgent,
ANDROID_VR_NO_AUTH.androidSdkVersion,
ANDROID_VR_NO_AUTH.clientVersion,
true),
ANDROID_UNPLUGGED(
29,
"ANDROID_UNPLUGGED",
"Google TV Streamer",
"14",
"com.google.android.apps.youtube.unplugged/8.49.0 (Linux; U; Android 14; GB) gzip",
"34",
"8.49.0",
true); // Requires login.
/**
* YouTube
@@ -87,11 +75,6 @@ public enum ClientType {
*/
public final boolean canLogin;
/**
* If a language code should be used.
*/
public final boolean useLanguageCode;
ClientType(int id,
String clientName,
String deviceModel,
@@ -99,8 +82,7 @@ public enum ClientType {
String userAgent,
@Nullable String androidSdkVersion,
String clientVersion,
boolean canLogin,
boolean useLanguageCode) {
boolean canLogin) {
this.id = id;
this.clientName = clientName;
this.deviceModel = deviceModel;
@@ -109,6 +91,5 @@ public enum ClientType {
this.androidSdkVersion = androidSdkVersion;
this.clientVersion = clientVersion;
this.canLogin = canLogin;
this.useLanguageCode = useLanguageCode;
}
}

View File

@@ -17,15 +17,30 @@ import app.revanced.extension.shared.spoof.requests.StreamingDataRequest;
public class SpoofVideoStreamsPatch {
private static final boolean SPOOF_STREAMING_DATA = BaseSettings.SPOOF_VIDEO_STREAMS.get();
private static final boolean FIX_HLS_CURRENT_TIME = SPOOF_STREAMING_DATA
&& BaseSettings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get() == ClientType.IOS;
/**
* Any unreachable ip address. Used to intentionally fail requests.
*/
private static final String UNREACHABLE_HOST_URI_STRING = "https://127.0.0.0";
private static final Uri UNREACHABLE_HOST_URI = Uri.parse(UNREACHABLE_HOST_URI_STRING);
/**
* @return If this patch was included during patching.
*/
private static boolean isPatchIncluded() {
return false; // Modified during patching.
}
public static final class NotSpoofingAndroidAvailability implements Setting.Availability {
@Override
public boolean isAvailable() {
if (SpoofVideoStreamsPatch.isPatchIncluded()) {
return !BaseSettings.SPOOF_VIDEO_STREAMS.get();
}
return true;
}
}
/**
* Injection point.
* Blocks /get_watch requests by returning an unreachable URI.
@@ -168,25 +183,4 @@ public class SpoofVideoStreamsPatch {
return postData;
}
/**
* Injection point.
*
* Fixes iOS livestreams starting from the beginning.
*/
public static boolean fixHLSCurrentTime(boolean original) {
if (FIX_HLS_CURRENT_TIME) {
return false;
}
return original;
}
public static final class SpoofiOSAvailability implements Setting.Availability {
@Override
public boolean isAvailable() {
return BaseSettings.SPOOF_VIDEO_STREAMS.get()
&& BaseSettings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get() == ClientType.IOS;
}
}
}

View File

@@ -37,9 +37,7 @@ final class PlayerRoutes {
JSONObject context = new JSONObject();
JSONObject client = new JSONObject();
if (clientType.useLanguageCode) {
client.put("hl", BaseSettings.SPOOF_VIDEO_STREAMS_LANGUAGE.get().getIso639_1());
}
client.put("hl", BaseSettings.SPOOF_VIDEO_STREAMS_LANGUAGE.get().getIso639_1());
client.put("clientName", clientType.clientName);
client.put("clientVersion", clientType.clientVersion);
client.put("deviceModel", clientType.deviceModel);

View File

@@ -22,6 +22,7 @@ import java.util.concurrent.TimeoutException;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils;
import app.revanced.extension.shared.settings.BaseSettings;
import app.revanced.extension.shared.spoof.AudioStreamLanguage;
import app.revanced.extension.shared.spoof.ClientType;
/**
@@ -35,21 +36,26 @@ import app.revanced.extension.shared.spoof.ClientType;
*/
public class StreamingDataRequest {
private static final ClientType[] CLIENT_ORDER_TO_USE;
private static final ClientType[] CLIENT_ORDER_TO_USE = ClientType.values();
private static final String AUTHORIZATION_HEADER = "Authorization";
private static final String[] REQUEST_HEADER_KEYS = {
AUTHORIZATION_HEADER, // Available only to logged-in users.
"X-GOOG-API-FORMAT-VERSION",
"X-Goog-Visitor-Id"
};
/**
* TCP connection and HTTP read timeout.
*/
private static final int HTTP_TIMEOUT_MILLISECONDS = 10 * 1000;
/**
* Any arbitrarily large value, but must be at least twice {@link #HTTP_TIMEOUT_MILLISECONDS}
*/
private static final int MAX_MILLISECONDS_TO_WAIT_FOR_FETCH = 20 * 1000;
private static final Map<String, StreamingDataRequest> cache = Collections.synchronizedMap(
new LinkedHashMap<>(100) {
/**
@@ -67,22 +73,8 @@ public class StreamingDataRequest {
}
});
static {
ClientType[] allClientTypes = ClientType.values();
ClientType preferredClient = BaseSettings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get();
CLIENT_ORDER_TO_USE = new ClientType[allClientTypes.length];
CLIENT_ORDER_TO_USE[0] = preferredClient;
int i = 1;
for (ClientType c : allClientTypes) {
if (c != preferredClient) {
CLIENT_ORDER_TO_USE[i++] = c;
}
}
}
private final String videoId;
private final Future<ByteBuffer> future;
private StreamingDataRequest(String videoId, Map<String, String> playerHeaders) {
@@ -172,13 +164,21 @@ public class StreamingDataRequest {
// Show an error if the last client type fails, or if the debug is enabled then show for all attempts.
final boolean showErrorToast = (++i == CLIENT_ORDER_TO_USE.length) || debugEnabled;
if (clientType == ClientType.ANDROID_VR_NO_AUTH
&& BaseSettings.SPOOF_VIDEO_STREAMS_LANGUAGE.get() == AudioStreamLanguage.DEFAULT) {
// Only use no auth Android VR if a non default audio language is selected.
continue;
}
HttpURLConnection connection = send(clientType, videoId, playerHeaders, showErrorToast);
if (connection != null) {
try {
// gzip encoding doesn't response with content length (-1),
// but empty response body does.
if (connection.getContentLength() == 0) {
Logger.printDebug(() -> "Received empty response for video: " + videoId);
if (BaseSettings.DEBUG.get()) {
Logger.printException(() -> "Ignoring empty client response: " + clientType);
}
} else {
try (InputStream inputStream = new BufferedInputStream(connection.getInputStream());
ByteArrayOutputStream baos = new ByteArrayOutputStream()) {

View File

@@ -6,7 +6,7 @@ import app.revanced.extension.youtube.settings.Settings;
@SuppressWarnings("unused")
public class ForceOriginalAudioPatch {
private static final String DEFAULT_AUDIO_TRACKS_IDENTIFIER = "original";
private static final String DEFAULT_AUDIO_TRACKS_SUFFIX = ".4";
/**
* Injection point.
@@ -17,7 +17,7 @@ public class ForceOriginalAudioPatch {
return isDefault;
}
if (audioTrackDisplayName.isEmpty()) {
if (audioTrackId.isEmpty()) {
// Older app targets can have empty audio tracks and these might be placeholders.
// The real audio tracks are called after these.
return isDefault;
@@ -26,7 +26,7 @@ public class ForceOriginalAudioPatch {
Logger.printDebug(() -> "default: " + String.format("%-5s", isDefault) + " id: "
+ String.format("%-8s", audioTrackId) + " name:" + audioTrackDisplayName);
final boolean isOriginal = audioTrackDisplayName.contains(DEFAULT_AUDIO_TRACKS_IDENTIFIER);
final boolean isOriginal = audioTrackId.endsWith(DEFAULT_AUDIO_TRACKS_SUFFIX);
if (isOriginal) {
Logger.printDebug(() -> "Using audio: " + audioTrackId);
}
@@ -34,8 +34,8 @@ public class ForceOriginalAudioPatch {
return isOriginal;
} catch (Exception ex) {
Logger.printException(() -> "isDefaultAudioStream failure", ex);
}
return isDefault;
return isDefault;
}
}
}

View File

@@ -0,0 +1,95 @@
package app.revanced.extension.youtube.patches;
import static app.revanced.extension.youtube.shared.NavigationBar.NavigationButton;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import java.lang.ref.WeakReference;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.youtube.settings.Settings;
@SuppressWarnings("unused")
public class OpenShortsInRegularPlayerPatch {
public enum ShortsPlayerType {
SHORTS_PLAYER,
REGULAR_PLAYER,
REGULAR_PLAYER_FULLSCREEN
}
static {
if (!VersionCheckPatch.IS_19_46_OR_GREATER
&& Settings.SHORTS_PLAYER_TYPE.get() == ShortsPlayerType.REGULAR_PLAYER_FULLSCREEN) {
// User imported newer settings to an older app target.
Logger.printInfo(() -> "Resetting " + Settings.SHORTS_PLAYER_TYPE);
Settings.SHORTS_PLAYER_TYPE.resetToDefault();
}
}
private static WeakReference<Activity> mainActivityRef = new WeakReference<>(null);
/**
* Injection point.
*/
public static void setMainActivity(Activity activity) {
mainActivityRef = new WeakReference<>(activity);
}
/**
* Injection point.
*/
public static boolean openShort(String videoID) {
try {
ShortsPlayerType type = Settings.SHORTS_PLAYER_TYPE.get();
if (type == ShortsPlayerType.SHORTS_PLAYER) {
return false; // Default unpatched behavior.
}
if (videoID.isEmpty()) {
// Shorts was opened using launcher app shortcut.
//
// This check will not detect if the Shorts app shortcut is used
// while the app is running in the background (instead the regular player is opened).
// To detect that the hooked method map parameter can be checked
// if integer key 'com.google.android.apps.youtube.app.endpoint.flags'
// has bitmask 16 set.
//
// This use case seems unlikely if the user has the Shorts
// set to open in the regular player, so it's ignored as
// checking the map makes the patch more complicated.
Logger.printDebug(() -> "Ignoring Short with no videoId");
return false;
}
if (NavigationButton.getSelectedNavigationButton() == NavigationButton.SHORTS) {
return false; // Always use Shorts player for the Shorts nav button.
}
final boolean forceFullScreen = (type == ShortsPlayerType.REGULAR_PLAYER_FULLSCREEN);
OpenVideosFullscreenHookPatch.setOpenNextVideoFullscreen(forceFullScreen);
// Can use the application context and add intent flags of
// FLAG_ACTIVITY_NEW_TASK and FLAG_ACTIVITY_CLEAR_TOP
// But the activity context seems to fix random app crashes
// if Shorts urls are opened outside the app.
var context = mainActivityRef.get();
Intent videoPlayerIntent = new Intent(
Intent.ACTION_VIEW,
Uri.parse("https://youtube.com/watch?v=" + videoID)
);
videoPlayerIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
videoPlayerIntent.setPackage(context.getPackageName());
context.startActivity(videoPlayerIntent);
return true;
} catch (Exception ex) {
OpenVideosFullscreenHookPatch.setOpenNextVideoFullscreen(null);
Logger.printException(() -> "openShort failure", ex);
return false;
}
}
}

View File

@@ -1,14 +0,0 @@
package app.revanced.extension.youtube.patches;
import app.revanced.extension.youtube.settings.Settings;
@SuppressWarnings("unused")
public class OpenVideosFullscreen {
/**
* Injection point.
*/
public static boolean openVideoFullscreenPortrait(boolean original) {
return Settings.OPEN_VIDEOS_FULLSCREEN_PORTRAIT.get();
}
}

View File

@@ -0,0 +1,41 @@
package app.revanced.extension.youtube.patches;
import androidx.annotation.Nullable;
import app.revanced.extension.youtube.settings.Settings;
@SuppressWarnings("unused")
public class OpenVideosFullscreenHookPatch {
@Nullable
private static volatile Boolean openNextVideoFullscreen;
public static void setOpenNextVideoFullscreen(@Nullable Boolean forceFullScreen) {
openNextVideoFullscreen = forceFullScreen;
}
/**
* Changed during patching since this class is also
* used by {@link OpenVideosFullscreenHookPatch}.
*/
private static boolean isFullScreenPatchIncluded() {
return false;
}
/**
* Injection point.
*/
public static boolean openVideoFullscreenPortrait(boolean original) {
Boolean openFullscreen = openNextVideoFullscreen;
if (openFullscreen != null) {
openNextVideoFullscreen = null;
return openFullscreen;
}
if (!isFullScreenPatchIncluded()) {
return false;
}
return Settings.OPEN_VIDEOS_FULLSCREEN_PORTRAIT.get();
}
}

View File

@@ -9,4 +9,5 @@ public class VersionCheckPatch {
public static final boolean IS_19_26_OR_GREATER = Utils.getAppVersionName().compareTo("19.26.00") >= 0;
public static final boolean IS_19_29_OR_GREATER = Utils.getAppVersionName().compareTo("19.29.00") >= 0;
public static final boolean IS_19_34_OR_GREATER = Utils.getAppVersionName().compareTo("19.34.00") >= 0;
public static final boolean IS_19_46_OR_GREATER = Utils.getAppVersionName().compareTo("19.46.00") >= 0;
}

View File

@@ -7,6 +7,7 @@ import static app.revanced.extension.shared.settings.Setting.migrateFromOldPrefe
import static app.revanced.extension.shared.settings.Setting.migrateOldSettingToNew;
import static app.revanced.extension.shared.settings.Setting.parent;
import static app.revanced.extension.shared.settings.Setting.parentsAny;
import static app.revanced.extension.shared.spoof.SpoofVideoStreamsPatch.NotSpoofingAndroidAvailability;
import static app.revanced.extension.youtube.patches.ChangeStartPagePatch.StartPage;
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerHideExpandCloseAvailability;
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerHorizontalDragAvailability;
@@ -16,6 +17,7 @@ import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerT
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType.MODERN_2;
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType.MODERN_3;
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType.MODERN_4;
import static app.revanced.extension.youtube.patches.OpenShortsInRegularPlayerPatch.ShortsPlayerType;
import static app.revanced.extension.youtube.patches.SeekbarThumbnailsPatch.SeekbarThumbnailsHighQualityAvailability;
import static app.revanced.extension.youtube.patches.VersionCheckPatch.IS_19_17_OR_GREATER;
import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.IGNORE;
@@ -52,7 +54,7 @@ public class Settings extends BaseSettings {
public static final StringSetting CUSTOM_PLAYBACK_SPEEDS = new StringSetting("revanced_custom_playback_speeds",
"0.25\n0.5\n0.75\n0.9\n0.95\n1.0\n1.05\n1.1\n1.25\n1.5\n1.75\n2.0\n3.0\n4.0\n5.0", true);
// Audio
public static final BooleanSetting FORCE_ORIGINAL_AUDIO = new BooleanSetting("revanced_force_original_audio", FALSE);
public static final BooleanSetting FORCE_ORIGINAL_AUDIO = new BooleanSetting("revanced_force_original_audio", FALSE, new NotSpoofingAndroidAvailability());
// Ads
public static final BooleanSetting HIDE_BUTTONED_ADS = new BooleanSetting("revanced_hide_buttoned_ads", TRUE);
@@ -224,6 +226,7 @@ public class Settings extends BaseSettings {
// Shorts
public static final BooleanSetting DISABLE_RESUMING_SHORTS_PLAYER = new BooleanSetting("revanced_disable_resuming_shorts_player", FALSE);
public static final BooleanSetting DISABLE_SHORTS_BACKGROUND_PLAYBACK = new BooleanSetting("revanced_shorts_disable_background_playback", FALSE);
public static final EnumSetting<ShortsPlayerType> SHORTS_PLAYER_TYPE = new EnumSetting<>("revanced_shorts_player_type", ShortsPlayerType.SHORTS_PLAYER);
public static final BooleanSetting HIDE_SHORTS_CHANNEL_BAR = new BooleanSetting("revanced_hide_shorts_channel_bar", FALSE);
public static final BooleanSetting HIDE_SHORTS_COMMENTS_BUTTON = new BooleanSetting("revanced_hide_shorts_comments_button", FALSE);
public static final BooleanSetting HIDE_SHORTS_DISLIKE_BUTTON = new BooleanSetting("revanced_hide_shorts_dislike_button", FALSE);

View File

@@ -1,85 +0,0 @@
package app.revanced.extension.youtube.settings.preference;
import static app.revanced.extension.shared.StringRef.str;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.Preference;
import android.preference.PreferenceManager;
import android.util.AttributeSet;
import androidx.annotation.Nullable;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils;
import app.revanced.extension.shared.settings.BaseSettings;
import app.revanced.extension.shared.settings.Setting;
import app.revanced.extension.shared.spoof.ClientType;
@SuppressWarnings({"deprecation", "unused"})
public class SpoofStreamingDataSideEffectsPreference extends Preference {
@Nullable
private ClientType currentClientType;
private final SharedPreferences.OnSharedPreferenceChangeListener listener = (sharedPreferences, str) -> {
// Because this listener may run before the ReVanced settings fragment updates Settings,
// this could show the prior config and not the current.
//
// Push this call to the end of the main run queue,
// so all other listeners are done and Settings is up to date.
Utils.runOnMainThread(this::updateUI);
};
public SpoofStreamingDataSideEffectsPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
public SpoofStreamingDataSideEffectsPreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public SpoofStreamingDataSideEffectsPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SpoofStreamingDataSideEffectsPreference(Context context) {
super(context);
}
private void addChangeListener() {
Setting.preferences.preferences.registerOnSharedPreferenceChangeListener(listener);
}
private void removeChangeListener() {
Setting.preferences.preferences.unregisterOnSharedPreferenceChangeListener(listener);
}
@Override
protected void onAttachedToHierarchy(PreferenceManager preferenceManager) {
super.onAttachedToHierarchy(preferenceManager);
updateUI();
addChangeListener();
}
@Override
protected void onPrepareForRemoval() {
super.onPrepareForRemoval();
removeChangeListener();
}
private void updateUI() {
ClientType clientType = BaseSettings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get();
if (currentClientType == clientType) {
return;
}
Logger.printDebug(() -> "Updating spoof stream side effects preference");
setEnabled(BaseSettings.SPOOF_VIDEO_STREAMS.get());
String key = "revanced_spoof_video_streams_about_"
+ clientType.name().toLowerCase();
setTitle(str(key + "_title"));
setSummary(str(key + "_summary"));
}
}

View File

@@ -150,11 +150,16 @@ public class SBRequester {
String end = String.format(Locale.US, TIME_TEMPLATE, endTime / 1000f);
String duration = String.format(Locale.US, TIME_TEMPLATE, videoLength / 1000f);
HttpURLConnection connection = getConnectionFromRoute(SBRoutes.SUBMIT_SEGMENTS, privateUserId, videoId, category, start, end, duration);
HttpURLConnection connection = getConnectionFromRoute(SBRoutes.SUBMIT_SEGMENTS,
privateUserId, videoId, category, start, end, duration);
final int responseCode = connection.getResponseCode();
String userMessage = switch (responseCode) {
case HTTP_STATUS_CODE_SUCCESS -> str("revanced_sb_submit_succeeded");
if (responseCode == HTTP_STATUS_CODE_SUCCESS) {
Utils.showToastLong(str("revanced_sb_submit_succeeded"));
return;
}
String userErrorMessage = switch (responseCode) {
case 409 -> str("revanced_sb_submit_failed_duplicate");
case 403 -> str("revanced_sb_submit_failed_forbidden",
Requester.parseErrorStringAndDisconnect(connection));
@@ -167,7 +172,7 @@ public class SBRequester {
// Message might be about the users account or an error too large to show in a toast.
// Use a dialog instead.
SponsorBlockUtils.showErrorDialog(userMessage);
SponsorBlockUtils.showErrorDialog(userErrorMessage);
} catch (SocketTimeoutException ex) {
Logger.printDebug(() -> "Timeout", ex);
Utils.showToastLong(str("revanced_sb_submit_failed_timeout"));

View File

@@ -3,4 +3,4 @@ org.gradle.jvmargs = -Xms512M -Xmx2048M
org.gradle.parallel = true
android.useAndroidX = true
kotlin.code.style = official
version = 5.5.2-dev.2
version = 5.7.1-dev.3

View File

@@ -1177,6 +1177,10 @@ public final class app/revanced/patches/youtube/layout/player/background/PlayerC
}
public final class app/revanced/patches/youtube/layout/player/fullscreen/OpenVideosFullscreenKt {
public static final fun getOpenVideosFullscreen ()Lapp/revanced/patcher/patch/BytecodePatch;
}
public final class app/revanced/patches/youtube/layout/player/fullscreen/OpenVideosFullscreenPatchKt {
public static final fun getOpenVideosFullscreenPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
@@ -1210,6 +1214,10 @@ public final class app/revanced/patches/youtube/layout/shortsautoplay/ShortsAuto
public static final fun getShortsAutoplayPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
public final class app/revanced/patches/youtube/layout/shortsplayer/OpenShortsInRegularPlayerPatchKt {
public static final fun getOpenShortsInRegularPlayerPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
public final class app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockPatchKt {
public static final fun getSponsorBlockPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}

View File

@@ -2,7 +2,7 @@ package app.revanced.patches.shared.misc.checks
import android.os.Build.*
import app.revanced.patcher.Fingerprint
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.patch.Patch
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patcher.util.proxy.mutableTypes.encodedValue.MutableEncodedValue
@@ -82,7 +82,7 @@ fun checkEnvironmentPatch(
}
}
fun invokeCheck() = mainActivityOnCreateFingerprint.method.addInstructions(
fun invokeCheck() = mainActivityOnCreateFingerprint.method.addInstruction(
0,
"invoke-static/range { p0 .. p0 },$EXTENSION_CLASS_DESCRIPTOR->check(Landroid/app/Activity;)V",
)

View File

@@ -1,7 +1,6 @@
package app.revanced.patches.shared.misc.spoof
import app.revanced.patcher.fingerprint
import app.revanced.util.literal
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
@@ -112,12 +111,11 @@ internal val buildMediaDataSourceFingerprint = fingerprint {
)
}
internal const val HLS_CURRENT_TIME_FEATURE_FLAG = 45355374L
internal val hlsCurrentTimeFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
parameters("Z", "L")
literal {
HLS_CURRENT_TIME_FEATURE_FLAG
internal val patchIncludedExtensionMethodFingerprint = fingerprint {
accessFlags(AccessFlags.PRIVATE, AccessFlags.STATIC)
returns("Z")
parameters()
custom { method, classDef ->
classDef.type == EXTENSION_CLASS_DESCRIPTOR && method.name == "isPatchIncluded"
}
}

View File

@@ -12,7 +12,7 @@ import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMu
import app.revanced.patches.all.misc.resources.addResourcesPatch
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.insertFeatureFlagBooleanOverride
import app.revanced.util.returnEarly
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation
@@ -39,6 +39,12 @@ fun spoofVideoStreamsPatch(
dependsOn(addResourcesPatch)
execute {
// region Enable extension helper method used by other patches
patchIncludedExtensionMethodFingerprint.method.returnEarly(true)
// endregion
// region Block /initplayback requests to fall back to /get_watch requests.
val moveUriStringIndex = buildInitPlaybackRequestFingerprint.patternMatch!!.startIndex
@@ -202,15 +208,6 @@ fun spoofVideoStreamsPatch(
}
// endregion
// region Fix iOS livestream current time.
hlsCurrentTimeFingerprint.method.insertFeatureFlagBooleanOverride(
HLS_CURRENT_TIME_FEATURE_FLAG,
"$EXTENSION_CLASS_DESCRIPTOR->fixHLSCurrentTime(Z)Z"
)
// endregion
executeBlock()
}
}

View File

@@ -11,8 +11,8 @@ import app.revanced.patches.shared.misc.mapping.resourceMappingPatch
import app.revanced.patches.shared.misc.mapping.resourceMappings
import app.revanced.patches.twitter.misc.extension.sharedExtensionPatch
import app.revanced.util.indexOfFirstLiteralInstructionOrThrow
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
internal var tweetShareLinkTemplateId = -1L
private set
@@ -25,15 +25,7 @@ internal val changeLinkSharingDomainResourcePatch = resourcePatch {
}
}
// This method is used to build the link that is shared when the "Share via..." button is pressed.
private const val FORMAT_METHOD_RESOURCE_REFERENCE =
"Lapp/revanced/extension/twitter/patches/links/ChangeLinkSharingDomainPatch;->" +
"formatResourceLink([Ljava/lang/Object;)Ljava/lang/String;"
// This method is used to build the link that is shared when the "Copy link" button is pressed.
private const val FORMAT_METHOD_REFERENCE =
"Lapp/revanced/extension/twitter/patches/links/ChangeLinkSharingDomainPatch;->" +
"formatLink(JLjava/lang/String;)Ljava/lang/String;"
private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/twitter/patches/links/ChangeLinkSharingDomainPatch;"
@Suppress("unused")
val changeLinkSharingDomainPatch = bytecodePatch(
@@ -71,7 +63,7 @@ val changeLinkSharingDomainPatch = bytecodePatch(
addInstructions(
0,
"""
invoke-static { p0, p1, p2 }, $FORMAT_METHOD_REFERENCE
invoke-static { p0, p1, p2 }, $EXTENSION_CLASS_DESCRIPTOR->formatLink(JLjava/lang/String;)Ljava/lang/String;
move-result-object p0
return-object p0
""",
@@ -84,12 +76,12 @@ val changeLinkSharingDomainPatch = bytecodePatch(
// Format the link with the new domain name register (1 instruction below the const).
val formatLinkCallIndex = templateIdConstIndex + 1
val formatLinkCall = getInstruction<Instruction35c>(formatLinkCallIndex)
val register = getInstruction<FiveRegisterInstruction>(formatLinkCallIndex).registerE
// Replace the original method call with the new method call.
replaceInstruction(
formatLinkCallIndex,
"invoke-static { v${formatLinkCall.registerE} }, $FORMAT_METHOD_RESOURCE_REFERENCE",
"invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->formatResourceLink([Ljava/lang/Object;)Ljava/lang/String;",
)
}
}

View File

@@ -77,6 +77,7 @@ val hideAdsPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -33,6 +33,7 @@ val hideGetPremiumPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -31,6 +31,7 @@ val videoAdsPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -61,6 +61,7 @@ val copyVideoUrlPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -32,6 +32,7 @@ val removeViewerDiscretionDialogPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -76,6 +76,7 @@ val downloadsPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -31,6 +31,7 @@ val disablePreciseSeekingGesturePatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -34,6 +34,7 @@ val enableSeekbarTappingPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -44,6 +44,7 @@ val enableSlideToSeekPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -37,6 +37,7 @@ val seekbarThumbnailsPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
)
)

View File

@@ -73,6 +73,7 @@ val swipeControlsPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -30,6 +30,7 @@ val autoCaptionsPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -51,6 +51,7 @@ val customBrandingPatch = resourcePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -49,6 +49,7 @@ val changeHeaderPatch = resourcePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
)
)

View File

@@ -30,6 +30,7 @@ val hideButtonsPatch = resourcePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -48,6 +48,7 @@ val navigationButtonsPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -62,6 +62,7 @@ val hidePlayerOverlayButtonsPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -64,6 +64,7 @@ val hideEndscreenCardsPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -37,6 +37,7 @@ val disableFullscreenAmbientModePatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -133,6 +133,7 @@ val hideLayoutComponentsPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -65,6 +65,7 @@ val hideInfoCardsPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -32,6 +32,7 @@ val hidePlayerFlyoutMenuPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -37,6 +37,7 @@ val disableRollingNumberAnimationPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -33,6 +33,7 @@ val hideSeekbarPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -190,6 +190,7 @@ val hideShortsComponentsPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -62,6 +62,7 @@ val disableSuggestedVideoEndScreenPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -29,6 +29,7 @@ val hideTimestampPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -170,6 +170,7 @@ val miniplayerPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -29,6 +29,7 @@ val playerPopupPanelsPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -20,6 +20,7 @@ val playerControlsBackgroundPatch = resourcePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -14,3 +14,15 @@ internal val openVideosFullscreenPortraitFingerprint = fingerprint {
OPEN_VIDEOS_FULLSCREEN_PORTRAIT_FEATURE_FLAG
}
}
/**
* Used to enable opening regular videos fullscreen.
*/
internal val openVideosFullscreenHookPatchExtensionFingerprint = fingerprint {
accessFlags(AccessFlags.PRIVATE, AccessFlags.STATIC)
returns("Z")
parameters()
custom { methodDef, classDef ->
methodDef.name == "isFullScreenPatchIncluded" && classDef.type == EXTENSION_CLASS_DESCRIPTOR
}
}

View File

@@ -1,46 +1,9 @@
package app.revanced.patches.youtube.layout.player.fullscreen
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.all.misc.resources.addResources
import app.revanced.patches.all.misc.resources.addResourcesPatch
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.settingsPatch
import app.revanced.util.insertFeatureFlagBooleanOverride
private const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/patches/OpenVideosFullscreen;"
@Suppress("unused")
val openVideosFullscreenPatch = bytecodePatch(
name = "Open videos fullscreen",
description = "Adds an option to open videos in full screen portrait mode.",
) {
dependsOn(
sharedExtensionPatch,
settingsPatch,
addResourcesPatch,
)
compatibleWith(
"com.google.android.youtube"(
"19.46.42",
)
)
execute {
openVideosFullscreenPortraitFingerprint.method.insertFeatureFlagBooleanOverride(
OPEN_VIDEOS_FULLSCREEN_PORTRAIT_FEATURE_FLAG,
"$EXTENSION_CLASS_DESCRIPTOR->openVideoFullscreenPortrait(Z)Z"
)
// Add resources and setting last, in case the user force patches an old incompatible version.
addResources("youtube", "layout.player.fullscreen.openVideosFullscreen")
PreferenceScreen.PLAYER.addPreferences(
SwitchPreference("revanced_open_videos_fullscreen_portrait")
)
}
}
@Deprecated("Renamed to openVideosFullscreenPatch", ReplaceWith("openVideosFullscreenPatch"))
val openVideosFullscreen = bytecodePatch{
dependsOn(openVideosFullscreenPatch)
}

View File

@@ -0,0 +1,32 @@
package app.revanced.patches.youtube.layout.player.fullscreen
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.youtube.layout.shortsplayer.openShortsInRegularPlayerPatch
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.playservice.is_19_46_or_greater
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
import app.revanced.util.insertFeatureFlagBooleanOverride
internal const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/patches/OpenVideosFullscreenHookPatch;"
/**
* Used by both [openVideosFullscreenPatch] and [openShortsInRegularPlayerPatch].
*/
internal val openVideosFullscreenHookPatch = bytecodePatch {
dependsOn(
sharedExtensionPatch,
versionCheckPatch
)
execute {
if (!is_19_46_or_greater) {
return@execute
}
openVideosFullscreenPortraitFingerprint.method.insertFeatureFlagBooleanOverride(
OPEN_VIDEOS_FULLSCREEN_PORTRAIT_FEATURE_FLAG,
"$EXTENSION_CLASS_DESCRIPTOR->openVideoFullscreenPortrait(Z)Z"
)
}
}

View File

@@ -0,0 +1,47 @@
package app.revanced.patches.youtube.layout.player.fullscreen
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.all.misc.resources.addResources
import app.revanced.patches.all.misc.resources.addResourcesPatch
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.misc.playservice.is_19_46_or_greater
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.settingsPatch
import app.revanced.util.returnEarly
@Suppress("unused")
val openVideosFullscreenPatch = bytecodePatch(
name = "Open videos fullscreen",
description = "Adds an option to open videos in full screen portrait mode.",
) {
dependsOn(
openVideosFullscreenHookPatch,
settingsPatch,
addResourcesPatch,
versionCheckPatch
)
compatibleWith(
"com.google.android.youtube"(
"19.46.42",
"19.47.53",
)
)
execute {
if (!is_19_46_or_greater) {
throw PatchException("'Open videos fullscreen' requires 19.46.42 or greater")
}
addResources("youtube", "layout.player.fullscreen.openVideosFullscreen")
PreferenceScreen.PLAYER.addPreferences(
SwitchPreference("revanced_open_videos_fullscreen_portrait")
)
// Enable the logic for the user Setting to open regular videos fullscreen.
openVideosFullscreenHookPatchExtensionFingerprint.method.returnEarly(true)
}
}

View File

@@ -60,6 +60,7 @@ val customPlayerOverlayOpacityPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -61,6 +61,7 @@ val returnYouTubeDislikePatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -37,6 +37,7 @@ val wideSearchbarPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -1,5 +1,6 @@
package app.revanced.patches.youtube.layout.shortsautoplay
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.bytecodePatch
@@ -39,6 +40,7 @@ val shortsAutoplayPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)
@@ -56,7 +58,7 @@ val shortsAutoplayPatch = bytecodePatch(
}
// Main activity is used to check if app is in pip mode.
mainActivityOnCreateFingerprint.method.addInstructions(
mainActivityOnCreateFingerprint.method.addInstruction(
1,
"invoke-static/range { p0 .. p0 }, $EXTENSION_CLASS_DESCRIPTOR->" +
"setMainActivity(Landroid/app/Activity;)V",

View File

@@ -0,0 +1,56 @@
package app.revanced.patches.youtube.layout.shortsplayer
import app.revanced.patcher.fingerprint
import app.revanced.util.literal
import com.android.tools.smali.dexlib2.AccessFlags
/**
* Purpose of this method is not clear, and it's only used to identify
* the obfuscated name of the videoId() method in PlaybackStartDescriptor.
*/
internal val playbackStartFeatureFlagFingerprint = fingerprint {
returns("Z")
parameters(
"Lcom/google/android/libraries/youtube/player/model/PlaybackStartDescriptor;",
)
literal {
45380134L
}
}
// Pre 19.25
internal val shortsPlaybackIntentLegacyFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returns("V")
parameters(
"L",
"Ljava/util/Map;",
"J",
"Ljava/lang/String;",
"Z",
"Ljava/util/Map;"
)
strings(
// None of these strings are unique.
"com.google.android.apps.youtube.app.endpoint.flags",
"ReelWatchFragmentArgs",
"reels_fragment_descriptor"
)
}
internal val shortsPlaybackIntentFingerprint = fingerprint {
accessFlags(AccessFlags.PROTECTED, AccessFlags.FINAL)
returns("V")
parameters(
"Lcom/google/android/libraries/youtube/player/model/PlaybackStartDescriptor;",
"Ljava/util/Map;",
"J",
"Ljava/lang/String;"
)
strings(
// None of these strings are unique.
"com.google.android.apps.youtube.app.endpoint.flags",
"ReelWatchFragmentArgs",
"reels_fragment_descriptor"
)
}

View File

@@ -0,0 +1,132 @@
package app.revanced.patches.youtube.layout.shortsplayer
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.all.misc.resources.addResources
import app.revanced.patches.all.misc.resources.addResourcesPatch
import app.revanced.patches.shared.misc.settings.preference.ListPreference
import app.revanced.patches.youtube.layout.player.fullscreen.openVideosFullscreenHookPatch
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.navigation.navigationBarHookPatch
import app.revanced.patches.youtube.misc.playservice.is_19_25_or_greater
import app.revanced.patches.youtube.misc.playservice.is_19_46_or_greater
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.settingsPatch
import app.revanced.patches.youtube.shared.mainActivityOnCreateFingerprint
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstructionOrThrow
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
private const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/youtube/patches/OpenShortsInRegularPlayerPatch;"
@Suppress("unused")
val openShortsInRegularPlayerPatch = bytecodePatch(
name = "Open Shorts in regular player",
description = "Adds options to open Shorts in the regular video player.",
) {
dependsOn(
sharedExtensionPatch,
settingsPatch,
addResourcesPatch,
openVideosFullscreenHookPatch,
navigationBarHookPatch,
versionCheckPatch
)
compatibleWith(
"com.google.android.youtube"(
"18.38.44",
"18.49.37",
"19.16.39",
"19.25.37",
"19.34.42",
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)
execute {
addResources("youtube", "layout.shortsplayer.shortsPlayerTypePatch")
PreferenceScreen.SHORTS.addPreferences(
if (is_19_46_or_greater) {
ListPreference(
key = "revanced_shorts_player_type",
summaryKey = null,
)
} else {
ListPreference(
key = "revanced_shorts_player_type",
summaryKey = null,
entriesKey = "revanced_shorts_player_type_legacy_entries",
entryValuesKey = "revanced_shorts_player_type_legacy_entry_values"
)
}
)
// Activity is used as the context to launch an Intent.
mainActivityOnCreateFingerprint.method.addInstruction(
1,
"invoke-static/range { p0 .. p0 }, ${EXTENSION_CLASS_DESCRIPTOR}->" +
"setMainActivity(Landroid/app/Activity;)V",
)
// Find the obfuscated method name for PlaybackStartDescriptor.videoId()
val playbackStartVideoIdMethodName = playbackStartFeatureFlagFingerprint.method.let {
val stringMethodIndex = it.indexOfFirstInstructionOrThrow {
val reference = getReference<MethodReference>()
reference?.definingClass == "Lcom/google/android/libraries/youtube/player/model/PlaybackStartDescriptor;"
&& reference.returnType == "Ljava/lang/String;"
}
navigate(it).to(stringMethodIndex).stop().name
}
fun extensionInstructions(playbackStartRegister: Int, freeRegister: Int) =
"""
invoke-virtual { v$playbackStartRegister }, Lcom/google/android/libraries/youtube/player/model/PlaybackStartDescriptor;->$playbackStartVideoIdMethodName()Ljava/lang/String;
move-result-object v$freeRegister
invoke-static { v$freeRegister }, $EXTENSION_CLASS_DESCRIPTOR->openShort(Ljava/lang/String;)Z
move-result v$freeRegister
if-eqz v$freeRegister, :disabled
return-void
:disabled
nop
"""
if (!is_19_25_or_greater) {
shortsPlaybackIntentLegacyFingerprint.method.apply {
val index = indexOfFirstInstructionOrThrow {
getReference<MethodReference>()?.returnType ==
"Lcom/google/android/libraries/youtube/player/model/PlaybackStartDescriptor;"
}
val freeRegister = getInstruction<FiveRegisterInstruction>(index).registerC
val playbackStartRegister = getInstruction<OneRegisterInstruction>(index + 1).registerA
addInstructionsWithLabels(
index + 2,
extensionInstructions(playbackStartRegister, freeRegister)
)
}
return@execute
}
shortsPlaybackIntentFingerprint.method.addInstructionsWithLabels(
0,
"""
move-object/from16 v0, p1
${extensionInstructions(0, 1)}
"""
)
}
}

View File

@@ -119,6 +119,7 @@ val sponsorBlockPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -40,6 +40,7 @@ val spoofAppVersionPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -37,6 +37,7 @@ val changeStartPagePatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -39,6 +39,7 @@ val disableResumingShortsOnStartupPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -34,6 +34,7 @@ val enableTabletLayoutPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -163,22 +163,31 @@ val themePatch = bytecodePatch(
}
// Fix the splash screen dark mode background color.
// In earlier versions of the app this is white and makes no sense for dark mode.
// This is only required for 19.32 and greater, but is applied to all targets.
// Only dark mode needs this fix as light mode correctly uses the custom color.
// In 19.32+ the dark mode splash screen is white and fades to black.
// Maybe it's a bug in YT, or maybe it intentionally. Who knows.
document("res/values-night/styles.xml").use { document ->
// Create a night mode specific override for the splash screen background.
val style = document.createElement("style")
style.setAttribute("name", "Theme.YouTube.Home")
style.setAttribute("parent", "@style/Base.V23.Theme.YouTube.Home")
val windowItem = document.createElement("item")
windowItem.setAttribute("name", "android:windowBackground")
windowItem.textContent = "@color/$splashBackgroundColor"
style.appendChild(windowItem)
val resourcesNode = document.getElementsByTagName("resources").item(0) as Element
resourcesNode.appendChild(style)
val childNodes = resourcesNode.childNodes
for (i in 0 until childNodes.length) {
val node = childNodes.item(i) as? Element ?: continue
val nodeAttributeName = node.getAttribute("name")
if (nodeAttributeName.startsWith("Theme.YouTube.Launcher")) {
val nodeAttributeParent = node.getAttribute("parent")
val style = document.createElement("style")
style.setAttribute("name", "Theme.YouTube.Home")
style.setAttribute("parent", nodeAttributeParent)
val windowItem = document.createElement("item")
windowItem.setAttribute("name", "android:windowBackground")
windowItem.textContent = "@color/$splashBackgroundColor"
style.appendChild(windowItem)
resourcesNode.removeChild(node)
resourcesNode.appendChild(style)
}
}
}
}
}
@@ -198,6 +207,7 @@ val themePatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -41,6 +41,7 @@ val alternativeThumbnailsPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -35,6 +35,7 @@ val bypassImageRegionRestrictionsPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -1,6 +1,6 @@
package app.revanced.patches.youtube.misc.announcements
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.all.misc.resources.addResources
import app.revanced.patches.all.misc.resources.addResourcesPatch
@@ -31,6 +31,7 @@ val announcementsPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)
@@ -41,7 +42,7 @@ val announcementsPatch = bytecodePatch(
SwitchPreference("revanced_announcements"),
)
mainActivityOnCreateFingerprint.method.addInstructions(
mainActivityOnCreateFingerprint.method.addInstruction(
// Insert index must be greater than the insert index used by GmsCoreSupport,
// as both patch the same method and GmsCore check should be first.
1,

View File

@@ -32,6 +32,7 @@ val autoRepeatPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -56,6 +56,7 @@ val backgroundPlaybackPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -40,6 +40,7 @@ val enableDebuggingPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -32,6 +32,7 @@ val spoofDeviceDimensionsPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -1,6 +1,6 @@
package app.revanced.patches.youtube.misc.dns
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.all.misc.resources.addResources
import app.revanced.patches.all.misc.resources.addResourcesPatch
@@ -25,13 +25,14 @@ val checkWatchHistoryDomainNameResolutionPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)
execute {
addResources("youtube", "misc.dns.checkWatchHistoryDomainNameResolutionPatch")
mainActivityOnCreateFingerprint.method.addInstructions(
mainActivityOnCreateFingerprint.method.addInstruction(
// FIXME: Insert index must be greater than the insert index used by GmsCoreSupport,
// as both patch the same method and GmsCoreSupport check should be first,
// but the patch does not depend on GmsCoreSupport, so it should not be possible to enforce this

View File

@@ -15,22 +15,16 @@ internal val onBackPressedFingerprint = fingerprint {
}
}
internal val recyclerViewScrollingFingerprint = fingerprint {
accessFlags(AccessFlags.PRIVATE, AccessFlags.FINAL)
internal val scrollPositionFingerprint = fingerprint {
accessFlags(AccessFlags.PROTECTED, AccessFlags.FINAL)
returns("V")
parameters()
parameters("L")
opcodes(
Opcode.IGET_OBJECT,
Opcode.IGET_OBJECT,
Opcode.IF_EQZ,
Opcode.IGET_OBJECT,
Opcode.CHECK_CAST,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.IF_LEZ,
Opcode.IGET_OBJECT,
Opcode.CONST_4,
Opcode.IF_NEZ,
Opcode.INVOKE_DIRECT,
Opcode.RETURN_VOID
)
strings("scroll_position")
}
internal val recyclerViewTopScrollingFingerprint = fingerprint {

View File

@@ -1,54 +1,49 @@
package app.revanced.patches.youtube.misc.fix.backtoexitgesture
import app.revanced.patcher.Fingerprint
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstructionOrThrow
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/FixBackToExitGesturePatch;"
internal val fixBackToExitGesturePatch = bytecodePatch(
description = "Fixes the swipe back to exit gesture.",
) {
execute {
/**
* Inject a call to a method from the extension.
*
* @param targetMethod The target method to call.
*/
fun Fingerprint.injectCall(targetMethod: ExtensionMethod) = method.addInstruction(
patternMatch!!.endIndex,
targetMethod.toString(),
)
recyclerViewTopScrollingFingerprint.match(recyclerViewTopScrollingParentFingerprint.originalClassDef)
.let {
it.method.addInstruction(
it.patternMatch!!.endIndex,
"invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->onTopView()V"
)
}
mapOf(
recyclerViewTopScrollingFingerprint.also {
it.match(recyclerViewTopScrollingParentFingerprint.originalClassDef)
} to ExtensionMethod(
methodName = "onTopView",
),
recyclerViewScrollingFingerprint to ExtensionMethod(
methodName = "onScrollingViews",
),
onBackPressedFingerprint to ExtensionMethod(
"p0",
"onBackPressed",
"Landroid/app/Activity;",
),
).forEach { (fingerprint, target) -> fingerprint.injectCall(target) }
scrollPositionFingerprint.let {
navigate(it.originalMethod)
.to(it.patternMatch!!.startIndex + 1)
.stop().apply {
val index = indexOfFirstInstructionOrThrow {
opcode == Opcode.INVOKE_VIRTUAL && getReference<MethodReference>()?.definingClass ==
"Landroid/support/v7/widget/RecyclerView;"
}
addInstruction(
index,
"invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->onScrollingViews()V"
)
}
}
onBackPressedFingerprint.let {
it.method.addInstruction(
it.patternMatch!!.endIndex,
"invoke-static { p0 }, $EXTENSION_CLASS_DESCRIPTOR->onBackPressed(Landroid/app/Activity;)V"
)
}
}
}
/**
* A reference to a method from the extension for [fixBackToExitGesturePatch].
*
* @param register The method registers.
* @param methodName The method name.
* @param parameterTypes The parameters of the method.
*/
private class ExtensionMethod(
val register: String = "",
val methodName: String,
val parameterTypes: String = "",
) {
override fun toString() =
"invoke-static {$register}, Lapp/revanced/extension/youtube/patches/FixBackToExitGesturePatch;->$methodName($parameterTypes)V"
}

View File

@@ -43,6 +43,7 @@ val gmsCoreSupportPatch = gmsCoreSupportPatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)
}

View File

@@ -38,6 +38,7 @@ val bypassURLRedirectsPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -49,6 +49,7 @@ val openLinksExternallyPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -38,6 +38,7 @@ val removeTrackingQueryParameterPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -20,6 +20,7 @@ val spoofVideoStreamsPatch = spoofVideoStreamsPatch({
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)
@@ -36,20 +37,11 @@ val spoofVideoStreamsPatch = spoofVideoStreamsPatch({
sorting = PreferenceScreenPreference.Sorting.UNSORTED,
preferences = setOf(
SwitchPreference("revanced_spoof_video_streams"),
ListPreference(
"revanced_spoof_video_streams_client",
summaryKey = null,
),
ListPreference(
"revanced_spoof_video_streams_language",
summaryKey = null
),
SwitchPreference("revanced_spoof_video_streams_ios_force_avc"),
// Preference requires a title but the actual text is chosen at runtime.
NonInteractivePreference(
key = "revanced_spoof_video_streams_about_android_vr",
tag = "app.revanced.extension.youtube.settings.preference.SpoofStreamingDataSideEffectsPreference"
),
NonInteractivePreference("revanced_spoof_video_streams_about")
),
),
)

View File

@@ -29,6 +29,7 @@ val zoomHapticsPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -31,7 +31,8 @@ private const val EXTENSION_CLASS_DESCRIPTOR =
@Suppress("unused")
val forceOriginalAudioPatch = bytecodePatch(
name = "Force original audio",
description = "Adds an option to always use the original audio track.",
description = "Adds an option to always use the original audio track. " +
"This patch does nothing if 'Spoof video streams' is enabled.",
) {
dependsOn(
sharedExtensionPatch,
@@ -49,6 +50,7 @@ val forceOriginalAudioPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -43,6 +43,7 @@ val rememberVideoQualityPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -27,6 +27,7 @@ val playbackSpeedPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)
}

View File

@@ -82,6 +82,7 @@ val restoreOldVideoQualityMenuPatch = bytecodePatch(
"19.43.41",
"19.45.38",
"19.46.42",
"19.47.53",
),
)

View File

@@ -164,6 +164,8 @@ Second \"item\" text"</string>
</patch>
<patch id="layout.startupshortsreset.disableResumingShortsOnStartupPatch">
</patch>
<patch id="layout.shortsplayer.shortsPlayerTypePatch">
</patch>
<patch id="layout.shortsautoplay.shortsAutoplayPatch">
</patch>
<patch id="layout.tablet.enableTabletLayoutPatch">

View File

@@ -164,6 +164,8 @@ Second \"item\" text"</string>
</patch>
<patch id="layout.startupshortsreset.disableResumingShortsOnStartupPatch">
</patch>
<patch id="layout.shortsplayer.shortsPlayerTypePatch">
</patch>
<patch id="layout.shortsautoplay.shortsAutoplayPatch">
</patch>
<patch id="layout.tablet.enableTabletLayoutPatch">

View File

@@ -1049,6 +1049,12 @@ Second \"item\" text"</string>
<string name="revanced_disable_resuming_shorts_player_summary_on">لن يتم استئناف تشغيل مشغل Shorts عند بدء تشغيل التطبيق</string>
<string name="revanced_disable_resuming_shorts_player_summary_off">سيتم استئناف تشغيل مشغل Shorts عند بدء تشغيل التطبيق</string>
</patch>
<patch id="layout.shortsplayer.shortsPlayerTypePatch">
<string name="revanced_shorts_player_type_title">فتح مقاطع الـShorts باستخدام</string>
<string name="revanced_shorts_player_type_shorts">مشغل Shorts</string>
<string name="revanced_shorts_player_type_regular_player">مشغل عادي</string>
<string name="revanced_shorts_player_type_regular_player_fullscreen">شاشة كاملة - مشغل عادي</string>
</patch>
<patch id="layout.shortsautoplay.shortsAutoplayPatch">
<string name="revanced_shorts_autoplay_title">التشغيل التلقائي لفيديوهات Shorts</string>
<string name="revanced_shorts_autoplay_summary_on">سيتم تشغيل فيديوهات Shorts تلقائيًا</string>
@@ -1280,20 +1286,12 @@ Second \"item\" text"</string>
قد لا يعمل تشغيل الفيديو"</string>
<string name="revanced_spoof_video_streams_user_dialog_message">إيقاف تشغيل هذا الإعداد قد يسبب مشاكل في تشغيل الفيديو.</string>
<string name="revanced_spoof_video_streams_client_title">العميل الافتراضي</string>
<string name="revanced_spoof_video_streams_ios_force_avc_title">فرض AVC (H.264)</string>
<string name="revanced_spoof_video_streams_ios_force_avc_summary_on">تم فرض ترميز الفيديو على AVC (H.264)</string>
<string name="revanced_spoof_video_streams_ios_force_avc_summary_off">يتم تحديد ترميز الفيديو تلقائيًا</string>
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">"قد يؤدي تمكين هذا إلى تحسين عمر البطارية وإصلاح مشكلة تقطيع التشغيل.
يتمتع تنسيق AVC بدقة قصوى تبلغ 1080P، برنامج ترميز الصوت Opus غير متوفر، وسيستخدم تشغيل الفيديو المزيد من بيانات الإنترنت مقارنةً بتنسيق VP9 أو AV1."</string>
<string name="revanced_spoof_video_streams_about_ios_title">التأثيرات الجانبية لمحاكاة iOS</string>
<string name="revanced_spoof_video_streams_about_ios_summary">"• لا يمكن تشغيل مقاطع فيديو الأطفال الخاصة.
• تنتهي مقاطع الفيديو مبكرًا بمقدار 1 ثانية."</string>
<string name="revanced_spoof_video_streams_about_android_vr_title">التأثيرات الجانبية لمحاكاة Android VR</string>
<string name="revanced_spoof_video_streams_about_android_vr_summary">"• قد لا يتم تشغيل فيديوهات الأطفال
• تبدأ البثوث المباشرة من البداية
• قد تنتهي الفيديوهات قبل النهاية بثانية واحدة"</string>
<string name="revanced_spoof_video_streams_client_type_title">العميل الافتراضي</string>
<string name="revanced_spoof_video_streams_about_title">آثار جانبية وهمية</string>
<string name="revanced_spoof_video_streams_about_summary">"- قد لا يتم تشغيل مقاطع فيديو للأطفال
- القائمة صوت المسار مفقودة
- مستوى الصوت الثابت غير متاح
- خيار فرض الصوت الأصلي غير متاح"</string>
<string name="revanced_spoof_video_streams_language_title">لغة البث الصوتي الافتراضية</string>
<string name="revanced_spoof_video_streams_language_DEFAULT">لغة التطبيق</string>
<string name="revanced_spoof_video_streams_language_AR">العربية</string>

View File

@@ -164,6 +164,8 @@ Second \"item\" text"</string>
</patch>
<patch id="layout.startupshortsreset.disableResumingShortsOnStartupPatch">
</patch>
<patch id="layout.shortsplayer.shortsPlayerTypePatch">
</patch>
<patch id="layout.shortsautoplay.shortsAutoplayPatch">
</patch>
<patch id="layout.tablet.enableTabletLayoutPatch">

View File

@@ -1049,6 +1049,12 @@ Sonradan söndürülərsə, UI səhvlərini qarşısını almaq üçün tətbiqi
<string name="revanced_disable_resuming_shorts_player_summary_on">Tətbiq açılanda Shorts oynadıcı davam etməyəcək</string>
<string name="revanced_disable_resuming_shorts_player_summary_off">Tətbiq açılanda Shorts oynadıcı davam edəcək</string>
</patch>
<patch id="layout.shortsplayer.shortsPlayerTypePatch">
<string name="revanced_shorts_player_type_title">Shorts ilə</string>
<string name="revanced_shorts_player_type_shorts">Shorts oynadıcı</string>
<string name="revanced_shorts_player_type_regular_player">Adi oynatıcı</string>
<string name="revanced_shorts_player_type_regular_player_fullscreen">Adi oynatıcı tam ekran</string>
</patch>
<patch id="layout.shortsautoplay.shortsAutoplayPatch">
<string name="revanced_shorts_autoplay_title">Shorts-ları avto-oynatma</string>
<string name="revanced_shorts_autoplay_summary_on">Shorts-lar avto-oynadılacaq</string>
@@ -1281,20 +1287,12 @@ Bunu aktivləşdirmə daha yüksək video keyfiyyətləri əngəlin silə bilər
Video oynatma işləməyə bilər"</string>
<string name="revanced_spoof_video_streams_user_dialog_message">Bu seçimi bağlamaq, video oynatma problemlərinə səbəb olar.</string>
<string name="revanced_spoof_video_streams_client_title">İlkin qəbuledici</string>
<string name="revanced_spoof_video_streams_ios_force_avc_title">Məcburi AVC (H.264)</string>
<string name="revanced_spoof_video_streams_ios_force_avc_summary_on">Video kodlama AVC (H.264) -yə məcbur edilir</string>
<string name="revanced_spoof_video_streams_ios_force_avc_summary_off">Video kodlama birbaşa yoxlanılır</string>
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">"Bunu fəallaşdırma, batareya ömrünü yaxşılaşdıra və oxutma ilişmələrini düzəldə bilər.
AVC-nin maksimum dəqiqliyi 1080p-dir, Opus səs kodek əlçatan deyil və video oxutma, VP9 və ya AV1-dən daha çox internet datası istifadə edəcək."</string>
<string name="revanced_spoof_video_streams_about_ios_title">iOS saxtakarlığı yan təsirləri</string>
<string name="revanced_spoof_video_streams_about_ios_summary">"◦ Xüsusi uşaq videoları bəlkə də oynanılmaya bilər
◦ Videolar 1 saniyə tez bitir"</string>
<string name="revanced_spoof_video_streams_about_android_vr_title">Android VR saxtakarlığı yan təsirləri</string>
<string name="revanced_spoof_video_streams_about_android_vr_summary">"• Uşaq videoları oxudulmaya bilər
• Canlı yayımlar başdan başlayır
• Videolar 1 saniyə tez bitir"</string>
<string name="revanced_spoof_video_streams_client_type_title">İlkin qəbuledici</string>
<string name="revanced_spoof_video_streams_about_title">Yan effektlərin spoof edilməsi</string>
<string name="revanced_spoof_video_streams_about_summary">"• Uşaq videoları işlənməyə bilər
• Səs izləri menyusunu itkindir
• Sabit səs mövcud deyil
• Orijinal səs məcburi olaraq mövcud deyil"</string>
<string name="revanced_spoof_video_streams_language_title">İlkin səs yayımı dili</string>
<string name="revanced_spoof_video_streams_language_DEFAULT">Tətbiq dili</string>
<string name="revanced_spoof_video_streams_language_AR">Ərəbcə</string>

View File

@@ -668,8 +668,8 @@ Second \"item\" text"</string>
<string name="revanced_hide_shorts_use_template_button_summary_on">Кнопка выкарыстання шаблону схавана</string>
<string name="revanced_hide_shorts_use_template_button_summary_off">Кнопка выкарыстання шаблону паказана</string>
<string name="revanced_hide_shorts_upcoming_button_title">Схаваць кнопку будучых</string>
<string name="revanced_hide_shorts_upcoming_button_summary_on">Кнопка ⬆️Будущие ролики⬆️ скрыта</string>
<string name="revanced_hide_shorts_upcoming_button_summary_off">Кнопка ⬆️Будущие ролики⬆️ отображается</string>
<string name="revanced_hide_shorts_upcoming_button_summary_on">Кнопка Будущие ролики скрыта</string>
<string name="revanced_hide_shorts_upcoming_button_summary_off">Кнопка Будущие ролики отображается</string>
<string name="revanced_hide_shorts_green_screen_button_title">Скрыть кнопку с зелёным экраном Shorts</string>
<string name="revanced_hide_shorts_green_screen_button_summary_on">Кнопка с зелёным экраном Shorts скрыта</string>
<string name="revanced_hide_shorts_green_screen_button_summary_off">Кнопка с зелёным экраном Shorts отображается</string>
@@ -1051,6 +1051,12 @@ Second \"item\" text"</string>
<string name="revanced_disable_resuming_shorts_player_summary_on">Прайгравальнік Shorts не аднаўляецца пры запуску праграмы</string>
<string name="revanced_disable_resuming_shorts_player_summary_off">Прайгравальнік Shorts адновіцца пры запуску праграмы</string>
</patch>
<patch id="layout.shortsplayer.shortsPlayerTypePatch">
<string name="revanced_shorts_player_type_title">Адкрыць Shorts з</string>
<string name="revanced_shorts_player_type_shorts">Прайгравальнік Shorts</string>
<string name="revanced_shorts_player_type_regular_player">Звычайны прайгравальнік</string>
<string name="revanced_shorts_player_type_regular_player_fullscreen">Звычайны прайгравальнік на ўвесь экран</string>
</patch>
<patch id="layout.shortsautoplay.shortsAutoplayPatch">
<string name="revanced_shorts_autoplay_title">Автовоспроизведение Shorts</string>
<string name="revanced_shorts_autoplay_summary_on">Shorts будут воспроизводиться автоматически</string>
@@ -1282,20 +1288,12 @@ Second \"item\" text"</string>
Прайграванне відэа можа не працаваць"</string>
<string name="revanced_spoof_video_streams_user_dialog_message">Адключэнне гэтай налады можа выклікаць праблемы з прайграваннем відэа.</string>
<string name="revanced_spoof_video_streams_client_title">Клиент по умолчанию</string>
<string name="revanced_spoof_video_streams_ios_force_avc_title">Принудительно AVC (H.264)</string>
<string name="revanced_spoof_video_streams_ios_force_avc_summary_on">Видеокодек принудительно установлен в AVC (H.264)</string>
<string name="revanced_spoof_video_streams_ios_force_avc_summary_off">Видеокодек определяется автоматически</string>
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">"Уключэнне гэтага можа палепшыць тэрмін службы батарэі і выправіць заіканне відэа.
AVC мае максімальную раздзяляльнасць 1080p, аўдыякадэкар Opus недаступны, і відэа будзе выкарыстоўваць больш Інтэрнэт-даных, чым VP9 або AV1."</string>
<string name="revanced_spoof_video_streams_about_ios_title">Пабочныя эфекты падмены iOS</string>
<string name="revanced_spoof_video_streams_about_ios_summary">"• Прыватныя дзіцячыя відэа могуць не прайгравацца
• Відэа заканчваюцца на 1 секунду раней"</string>
<string name="revanced_spoof_video_streams_about_android_vr_title">Побочные эффекты подмены Android VR</string>
<string name="revanced_spoof_video_streams_about_android_vr_summary">"• Дзіцячыя відэа могуць не прайгравацца
• Трансляцыі ў прамым эфіры пачынаюцца з пачатку
• Відэа заканчваюцца на 1 секунду раней"</string>
<string name="revanced_spoof_video_streams_client_type_title">Клиент по умолчанию</string>
<string name="revanced_spoof_video_streams_about_title">Падробка пабочных эфектаў</string>
<string name="revanced_spoof_video_streams_about_summary">"• Дзіцячыя відэа могуць не прайгравацца
• Панэль гукавых дарожак адсутнічае
• Стабільная гучнасць недаступная
• Прымусова арыгінальная аўдыёдарожка недаступная"</string>
<string name="revanced_spoof_video_streams_language_title">Язык потока аудио по умолчанию</string>
<string name="revanced_spoof_video_streams_language_DEFAULT">Язык приложения</string>
<string name="revanced_spoof_video_streams_language_AR">Арабский</string>

View File

@@ -1049,6 +1049,12 @@ Second \"item\" text"</string>
<string name="revanced_disable_resuming_shorts_player_summary_on">Shorts плейъра при стартиране на приложението е скрит</string>
<string name="revanced_disable_resuming_shorts_player_summary_off">Shorts плейъра при стартиране на приложението се показва</string>
</patch>
<patch id="layout.shortsplayer.shortsPlayerTypePatch">
<string name="revanced_shorts_player_type_title">Отворете Shorts с</string>
<string name="revanced_shorts_player_type_shorts">Играч на Shorts</string>
<string name="revanced_shorts_player_type_regular_player">Обикновен плейър</string>
<string name="revanced_shorts_player_type_regular_player_fullscreen">Обикновен плейър на цял екран</string>
</patch>
<patch id="layout.shortsautoplay.shortsAutoplayPatch">
<string name="revanced_shorts_autoplay_title">Автоматично пускане Shorts</string>
<string name="revanced_shorts_autoplay_summary_on">Shorts ще се пускат автоматично</string>
@@ -1280,20 +1286,12 @@ Second \"item\" text"</string>
Възпроизвеждането на видеоклипове може да не работи"</string>
<string name="revanced_spoof_video_streams_user_dialog_message">Деактивирането на тази настройка ще доведе до проблеми с възпроизвеждането на видео.</string>
<string name="revanced_spoof_video_streams_client_title">Клиент по подразбиране</string>
<string name="revanced_spoof_video_streams_ios_force_avc_title">Принудително AVC (H.264)</string>
<string name="revanced_spoof_video_streams_ios_force_avc_summary_on">Видео кодек по подразбиране AVC (H.264)</string>
<string name="revanced_spoof_video_streams_ios_force_avc_summary_off">Видео кодекът се определя автоматично</string>
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">"Активирането на това може да подобри живота на батерията и да поправи заекването на възпроизвеждането.
AVC има максимална разделителна способност от 1080p, аудио кодекът Opus не е наличен, а видеовъзпроизвеждането ще използва повече интернет данни от VP9 или AV1."</string>
<string name="revanced_spoof_video_streams_about_ios_title">ранични ефекти от подмяната на iOS</string>
<string name="revanced_spoof_video_streams_about_ios_summary">"• Възможно е частните детски видеоклипове да не се възпроизвеждат
• Видеоклиповете завършват 1 секунда по-рано"</string>
<string name="revanced_spoof_video_streams_about_android_vr_title">Странични ефекти от подправяне на Android VR</string>
<string name="revanced_spoof_video_streams_about_android_vr_summary">"• Детските видеоклипове може да не се възпроизвеждат
• Предаванията на живо започват от началото
• Видеоклиповете завършват 1 секунда по-рано"</string>
<string name="revanced_spoof_video_streams_client_type_title">Клиент по подразбиране</string>
<string name="revanced_spoof_video_streams_about_title">Фалшиви странични ефекти</string>
<string name="revanced_spoof_video_streams_about_summary">"• Детските видеоклипове може да не се възпроизвеждат
• Липсва менюто за аудио запис
Не е наличен стабилен звук
• Принудително оригинално аудио не е налично"</string>
<string name="revanced_spoof_video_streams_language_title">Език по подразбиране на аудио потока</string>
<string name="revanced_spoof_video_streams_language_DEFAULT">Език на приложението</string>
<string name="revanced_spoof_video_streams_language_AR">Арабски</string>

View File

@@ -1050,6 +1050,12 @@ MicroG-এর জন্য ব্যাটারি অপ্টিমাইজ
<string name="revanced_disable_resuming_shorts_player_summary_on">অ্যাপের শুরুতে Shorts প্লেয়ার আবার চলবে না</string>
<string name="revanced_disable_resuming_shorts_player_summary_off">অ্যাপের শুরুতে Shorts প্লেয়ার আবার চলবে</string>
</patch>
<patch id="layout.shortsplayer.shortsPlayerTypePatch">
<string name="revanced_shorts_player_type_title">Shorts সঙ্গে খুলুন</string>
<string name="revanced_shorts_player_type_shorts">Shorts প্লেয়ার</string>
<string name="revanced_shorts_player_type_regular_player">নিয়মিত প্লেয়ার</string>
<string name="revanced_shorts_player_type_regular_player_fullscreen">নিয়মিত প্লেয়ার পূর্ণ পর্দা</string>
</patch>
<patch id="layout.shortsautoplay.shortsAutoplayPatch">
<string name="revanced_shorts_autoplay_title">অটোপ্লে Shorts</string>
<string name="revanced_shorts_autoplay_summary_on">Shorts অটোপ্লে হবে</string>
@@ -1282,19 +1288,12 @@ DeArrow সম্পর্কে আরও জানতে এখানে ট
ভিডিও প্লেব্যাক কাজ নাও করতে পারে"</string>
<string name="revanced_spoof_video_streams_user_dialog_message">এই সেটিংটি বন্ধ করার ফলে ভিডিও প্লেব্যাক ত্রুটি হতে পারে।</string>
<string name="revanced_spoof_video_streams_client_title">ডিফল্ট ক্লায়েন্ট</string>
<string name="revanced_spoof_video_streams_ios_force_avc_title">AVC (H.264) ফোর্স করুন</string>
<string name="revanced_spoof_video_streams_ios_force_avc_summary_on">ভিডিও কোডেক AVC (H.264) তে বাধ্য করা হয়েছে</string>
<string name="revanced_spoof_video_streams_ios_force_avc_summary_off">ভিডিও কোডেক স্বয়ংক্রিয়ভাবে নির্ধারিত হচ্ছে</string>
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">"এটি সক্রিয় করা ব্যাটারি লাইফ উন্নত করতে পারে এবং প্লেব্যাক হোঁচট খাওয়া ঠিক করতে পারে।
AVC-এর সর্বোচ্চ রেজোলিউশন 1080p, Opus অডিও কোডেক উপলব্ধ নয় এবং ভিডিও প্লেব্যাক VP9 বা AV1 এর তুলনায় আরও ইন্টারনেট ডেটা ব্যবহার করবে।"</string>
<string name="revanced_spoof_video_streams_about_ios_title">iOS স্পুফিং এর পার্শ্ব প্রতিক্রিয়া</string>
<string name="revanced_spoof_video_streams_about_ios_summary">"• বেসরকারি শিশু ভিডিও চলতে নাও পারে&lt;br&gt;• ভিডিওগুলি 1 সেকেন্ড আগে শেষ হয়"</string>
<string name="revanced_spoof_video_streams_about_android_vr_title">Android VR স্পুফিং এর পার্শ্ব প্রতিক্রিয়া</string>
<string name="revanced_spoof_video_streams_about_android_vr_summary">"• শিশু ভিডিওগুলি প্লে নাও হতে পারে
• লাইভস্ট্রিম শুরু থেকে শুরু হয়
• ভিডিও 1 সেকেন্ড আগে শেষ হয়"</string>
<string name="revanced_spoof_video_streams_client_type_title">ডিফল্ট ক্লায়েন্ট</string>
<string name="revanced_spoof_video_streams_about_title">স্পুফিং এর পার্শ্বপ্রতিক্রিয়া</string>
<string name="revanced_spoof_video_streams_about_summary">"• বাচ্চাদের ভিডিও প্লে নাও হতে পারে
• অডিও ট্র্যাক মেনু অনুপস্থিত
• স্থিতিশীল ভলিউম উপলব্ধ নয়
• জোর করে মূল অডিও উপলব্ধ নয়৷"</string>
<string name="revanced_spoof_video_streams_language_title">ডিফল্ট অডিও স্ট্রিম ভাষা</string>
<string name="revanced_spoof_video_streams_language_DEFAULT">অ্যাপ ভাষা</string>
<string name="revanced_spoof_video_streams_language_AR">আরবি</string>

View File

@@ -164,6 +164,8 @@ Second \"item\" text"</string>
</patch>
<patch id="layout.startupshortsreset.disableResumingShortsOnStartupPatch">
</patch>
<patch id="layout.shortsplayer.shortsPlayerTypePatch">
</patch>
<patch id="layout.shortsautoplay.shortsAutoplayPatch">
</patch>
<patch id="layout.tablet.enableTabletLayoutPatch">

View File

@@ -1049,6 +1049,12 @@ Si després es desactiva, es recomana esborrar les dades de l'aplicació per evi
<string name="revanced_disable_resuming_shorts_player_summary_on">El reproductor de Shorts no es reprendrà a l\'inici de l\'aplicació</string>
<string name="revanced_disable_resuming_shorts_player_summary_off">El reproductor de Shorts es reprendrà a l\'inici de l\'aplicació</string>
</patch>
<patch id="layout.shortsplayer.shortsPlayerTypePatch">
<string name="revanced_shorts_player_type_title">Obre Youtube Shorts amb</string>
<string name="revanced_shorts_player_type_shorts">Reproductor de Shorts</string>
<string name="revanced_shorts_player_type_regular_player">Reproductor normal</string>
<string name="revanced_shorts_player_type_regular_player_fullscreen">Reproductor normal a pantalla completa</string>
</patch>
<patch id="layout.shortsautoplay.shortsAutoplayPatch">
<string name="revanced_shorts_autoplay_title">Reprodueix automàticament els Shorts</string>
<string name="revanced_shorts_autoplay_summary_on">Els Shorts es reproduiran automàticament</string>
@@ -1281,20 +1287,12 @@ Si actives aquesta opció, es poden desbloquejar qualitats de vídeo més altes"
La reproducció de vídeo pot no funcionar"</string>
<string name="revanced_spoof_video_streams_user_dialog_message">Desactivar aquesta configuració pot causar problemes de reproducció de vídeo.</string>
<string name="revanced_spoof_video_streams_client_title">Client predeterminat</string>
<string name="revanced_spoof_video_streams_ios_force_avc_title">Força AVC (H.264)</string>
<string name="revanced_spoof_video_streams_ios_force_avc_summary_on">El còdec de vídeo es força a AVC (H.264)</string>
<string name="revanced_spoof_video_streams_ios_force_avc_summary_off">El còdec de vídeo es determina automàticament</string>
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">"Si actives aquesta opció, és possible que millori la durada de la bateria i es solucioni el tartamudeig de la reproducció.
AVC té una resolució màxima de 1080p, el còdec d'àudio Opus no està disponible i la reproducció de vídeo utilitzarà més dades d'Internet que VP9 o AV1."</string>
<string name="revanced_spoof_video_streams_about_ios_title">Efectes secundaris de la falsificació d\'iOS</string>
<string name="revanced_spoof_video_streams_about_ios_summary">"• Els vídeos privats per a nens potser no es reprodueixen
• Els vídeos finalitzen 1 segon abans"</string>
<string name="revanced_spoof_video_streams_about_android_vr_title">Efecte secundaris de la suplantació d\'Android VR</string>
<string name="revanced_spoof_video_streams_about_android_vr_summary">"• Els vídeos de nens poden no reproduir-se
• Les emissions en directe comencen des del principi
• Els vídeos acaben 1 segon abans"</string>
<string name="revanced_spoof_video_streams_client_type_title">Client predeterminat</string>
<string name="revanced_spoof_video_streams_about_title">Efectes secundaris de suplantació</string>
<string name="revanced_spoof_video_streams_about_summary">"• És possible que els vídeos infantils no es reprodueixin
• Falta el menú de pista d'àudio
• El volum estable no està disponible
• Força l'àudio original no està disponible"</string>
<string name="revanced_spoof_video_streams_language_title">Idioma de la transmissió d\'àudio per defecte</string>
<string name="revanced_spoof_video_streams_language_DEFAULT">Idioma de l\'aplicació</string>
<string name="revanced_spoof_video_streams_language_AR">Àrab</string>

View File

@@ -1049,6 +1049,12 @@ Pokud bude později vypnuta, doporučujeme vymazat data aplikace, aby se zabrán
<string name="revanced_disable_resuming_shorts_player_summary_on">Přehrávač Shorts nebude obnoven při spuštění aplikace</string>
<string name="revanced_disable_resuming_shorts_player_summary_off">Přehrávač Shorts se po spuštění aplikace znovu spustí</string>
</patch>
<patch id="layout.shortsplayer.shortsPlayerTypePatch">
<string name="revanced_shorts_player_type_title">Otevřít Shorts s</string>
<string name="revanced_shorts_player_type_shorts">Přehrávač Shorts</string>
<string name="revanced_shorts_player_type_regular_player">Běžný přehrávač</string>
<string name="revanced_shorts_player_type_regular_player_fullscreen">Normální přehrávač (celá obrazovka)</string>
</patch>
<patch id="layout.shortsautoplay.shortsAutoplayPatch">
<string name="revanced_shorts_autoplay_title">Automatické přehrávání Shorts</string>
<string name="revanced_shorts_autoplay_summary_on">Shorts se budou automaticky přehrávat</string>
@@ -1280,20 +1286,12 @@ Povolením této funkce lze odemknout vyšší kvality videa"</string>
Přehrávání videa nemusí fungovat"</string>
<string name="revanced_spoof_video_streams_user_dialog_message">Vypnutí tohoto nastavení může způsobit problémy s přehráváním videa.</string>
<string name="revanced_spoof_video_streams_client_title">Výchozí klient</string>
<string name="revanced_spoof_video_streams_ios_force_avc_title">Vynutit AVC (H.264)</string>
<string name="revanced_spoof_video_streams_ios_force_avc_summary_on">Video kodek je vynucen na AVC (H.264)</string>
<string name="revanced_spoof_video_streams_ios_force_avc_summary_off">Video kodek je určen automaticky</string>
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">"Povolením této funkce se může zlepšit výdrž baterie a opravit zadrhávání přehrávání.
AVC má maximální rozlišení 1080p, audio kodek Opus není dostupný a přehrávání videa bude používat více internetových dat než VP9 nebo AV1."</string>
<string name="revanced_spoof_video_streams_about_ios_title">Vedlejší účinky napodobování iOS</string>
<string name="revanced_spoof_video_streams_about_ios_summary">"• Soukromá dětská videa se nemusí přehrávat
• Videa končí o 1 sekundu dříve"</string>
<string name="revanced_spoof_video_streams_about_android_vr_title">Vedlejší účinky napodobování Android VR</string>
<string name="revanced_spoof_video_streams_about_android_vr_summary">"• Videa pro děti se nemusí přehrát
• Livestreamy začínají od začátku
• Videa končí o 1 sekundu dříve"</string>
<string name="revanced_spoof_video_streams_client_type_title">Výchozí klient</string>
<string name="revanced_spoof_video_streams_about_title">Napodobování vedlejších účinků</string>
<string name="revanced_spoof_video_streams_about_summary">"• Dětská videa se nemusí přehrávat
• Chybí nabídka zvukových stop
• Stabilní hlasitost není k dispozici
• Vynucení původního zvuku není k dispozici"</string>
<string name="revanced_spoof_video_streams_language_title">Výchozí jazyk zvukového streamu</string>
<string name="revanced_spoof_video_streams_language_DEFAULT">Jazyk aplikace</string>
<string name="revanced_spoof_video_streams_language_AR">Arabsky</string>

View File

@@ -1050,6 +1050,12 @@ Hvis det senere slås fra, anbefales det at rydde app-dataene for at forhindre U
<string name="revanced_disable_resuming_shorts_player_summary_on">Shorts-afspilleren genoptages ikke ved app-start</string>
<string name="revanced_disable_resuming_shorts_player_summary_off">Kortspilleren vil genoptage ved app-opstart</string>
</patch>
<patch id="layout.shortsplayer.shortsPlayerTypePatch">
<string name="revanced_shorts_player_type_title">Åbne Shorts med</string>
<string name="revanced_shorts_player_type_shorts">Shorts-afspiller</string>
<string name="revanced_shorts_player_type_regular_player">Standardafspiller</string>
<string name="revanced_shorts_player_type_regular_player_fullscreen">Standardafspiller i fuld skærm</string>
</patch>
<patch id="layout.shortsautoplay.shortsAutoplayPatch">
<string name="revanced_shorts_autoplay_title">Automatisk afspilning af Shorts</string>
<string name="revanced_shorts_autoplay_summary_on">Shorts afspilles automatisk</string>
@@ -1281,20 +1287,12 @@ Aktivering af dette kan låse op for højere videokvalitet"</string>
Videoafspilning virker muligvis ikke"</string>
<string name="revanced_spoof_video_streams_user_dialog_message">At slå denne indstilling fra kan forårsage problemer med videoafspilning.</string>
<string name="revanced_spoof_video_streams_client_title">Standard klient</string>
<string name="revanced_spoof_video_streams_ios_force_avc_title">Gennemtving AVC (H.264)</string>
<string name="revanced_spoof_video_streams_ios_force_avc_summary_on">Video-codec er tvunget til AVC (H.264)</string>
<string name="revanced_spoof_video_streams_ios_force_avc_summary_off">Video-codec bestemmes automatisk</string>
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">"Aktivering af dette kan forbedre batterilevetiden og løse afspilningshakkethed.
AVC har en maksimal opløsning på 1080p, Opus lydcodec er ikke tilgængelig, og videoafspilning bruger mere internetdata end VP9 eller AV1."</string>
<string name="revanced_spoof_video_streams_about_ios_title">iOS forfalskning bivirkninger</string>
<string name="revanced_spoof_video_streams_about_ios_summary">"• Private børnevideoer kan muligvis ikke afspilles
• Videoer slutter 1 sekund før"</string>
<string name="revanced_spoof_video_streams_about_android_vr_title">Android VR spoofing bivirkninger</string>
<string name="revanced_spoof_video_streams_about_android_vr_summary">"• Børnevideoer kan ikke afspilles
• Livestreams starter fra begyndelsen
• Videoer slutter 1 sekund tidligere"</string>
<string name="revanced_spoof_video_streams_client_type_title">Standard klient</string>
<string name="revanced_spoof_video_streams_about_title">Overskrivning af bivirkninger</string>
<string name="revanced_spoof_video_streams_about_summary">"• Børnevideoer afspilles muligvis ikke
• Menuen for lydspor mangler
• Stabil lydstyrke er ikke tilgængelig
• Force original lyd er ikke tilgængelig"</string>
<string name="revanced_spoof_video_streams_language_title">Standard lyd-stream sprog</string>
<string name="revanced_spoof_video_streams_language_DEFAULT">App sprog</string>
<string name="revanced_spoof_video_streams_language_AR">Arabisk</string>

View File

@@ -1044,6 +1044,12 @@ Wenn Sie die Funktion später deaktivieren, wird empfohlen, die App-Daten zu lö
<string name="revanced_disable_resuming_shorts_player_summary_on">Der Shorts Player wird beim Start der App nicht fortgesetzt</string>
<string name="revanced_disable_resuming_shorts_player_summary_off">Shorts-Player wird beim Start der App fortgesetzt</string>
</patch>
<patch id="layout.shortsplayer.shortsPlayerTypePatch">
<string name="revanced_shorts_player_type_title">Shorts mit</string>
<string name="revanced_shorts_player_type_shorts">Shorts Spieler</string>
<string name="revanced_shorts_player_type_regular_player">Normaler Spieler</string>
<string name="revanced_shorts_player_type_regular_player_fullscreen">Normaler Spieler im Vollbildmodus</string>
</patch>
<patch id="layout.shortsautoplay.shortsAutoplayPatch">
<string name="revanced_shorts_autoplay_title">Shorts automatisch abspielen</string>
<string name="revanced_shorts_autoplay_summary_on">Shorts werden autoplay</string>
@@ -1275,20 +1281,12 @@ Durch Aktivieren dieser Option können höhere Videoqualitäten freigeschaltet w
Die Videowiedergabe funktioniert möglicherweise nicht"</string>
<string name="revanced_spoof_video_streams_user_dialog_message">Das Deaktivieren dieser Einstellung kann zu Videowiedergabeproblemen führen.</string>
<string name="revanced_spoof_video_streams_client_title">Standard-Client</string>
<string name="revanced_spoof_video_streams_ios_force_avc_title">AVC erzwingen (H.264)</string>
<string name="revanced_spoof_video_streams_ios_force_avc_summary_on">Video-Codec ist zu AVC gezwungen (H.264)</string>
<string name="revanced_spoof_video_streams_ios_force_avc_summary_off">Video-Codec wird automatisch bestimmt</string>
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">"Dadurch kann die Akkulaufzeit verbessert und Stottern bei der Wiedergabe behoben werden.
AVC hat eine maximale Auflösung von 1080p, der Opus-Audiocodec ist nicht verfügbar und die Videowiedergabe verbraucht mehr Internetdaten als VP9 oder AV1."</string>
<string name="revanced_spoof_video_streams_about_ios_title">iOS Spoofing Nebeneffekte</string>
<string name="revanced_spoof_video_streams_about_ios_summary">"• Private Kindervideos werden möglicherweise nicht abgespielt
• Videos enden 1 Sekunde früher"</string>
<string name="revanced_spoof_video_streams_about_android_vr_title">Android VR Spoofing Nebeneffekte</string>
<string name="revanced_spoof_video_streams_about_android_vr_summary">"• Kindervideos werden möglicherweise nicht abgespielt
• Livestreams starten von Anfang an
• Videos enden 1 Sekunde früher"</string>
<string name="revanced_spoof_video_streams_client_type_title">Standard-Client</string>
<string name="revanced_spoof_video_streams_about_title">Spoofing-Nebenwirkungen</string>
<string name="revanced_spoof_video_streams_about_summary">"• Kindervideos werden möglicherweise nicht abgespielt
• Audiospurmenü fehlt
• Eine stabile Lautstärke ist nicht verfügbar
• „Originalton erzwingen“ ist nicht verfügbar"</string>
<string name="revanced_spoof_video_streams_language_title">Standard Audio Streamsprache</string>
<string name="revanced_spoof_video_streams_language_DEFAULT">App-Sprache</string>
<string name="revanced_spoof_video_streams_language_AR">Arabisch</string>

Some files were not shown because too many files have changed in this diff Show More