Skip to content

Commit 74fe9a5

Browse files
committed
fixed bckground song playing issue
1 parent 8a9b8d0 commit 74fe9a5

8 files changed

Lines changed: 237 additions & 179 deletions

File tree

Api/InnertubeClient.js

Lines changed: 163 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66
*/
77

88
import { enhanceYTMusicArtwork } from '../Utils/ArtworkEnhancer';
9+
import { getCachedData, CACHE_GROUPS } from './CacheManager';
10+
11+
// Cache constants for home feed
12+
const HOME_FEED_CACHE_KEY = 'ytmusic_home_sections_unified';
13+
const HOME_FEED_CACHE_TTL_MINUTES = 1440; // 24 hours
914

1015
const INNERTUBE_API_KEY = 'AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8';
1116
const INNERTUBE_API_URL = 'https://music.youtube.com/youtubei/v1';
@@ -192,145 +197,186 @@ class InnerTubeClient {
192197
return null;
193198
}
194199
}
195-
/**
196-
* Get Home Feed with continuation support
197-
* Fetches sections by following continuation tokens and chips (like OuterTune)
198-
* @param {number} sectionLimit - Maximum number of sections to fetch
199-
*/
200-
static async getHome(sectionLimit = 20) {
201-
let authCookies = null;
200+
/**
201+
* Get Home Feed - cache-aware wrapper
202+
* Checks cache first, fetches fresh if cache miss or forceRefresh
203+
* @param {number} sectionLimit - Maximum number of sections to fetch
204+
* @param {boolean} forceRefresh - Skip cache if true
205+
* @returns {Promise<Array>} Array of home feed sections
206+
*/
207+
static async getHome(sectionLimit = 20, forceRefresh = false) {
208+
if (forceRefresh) {
209+
// Skip cache on force refresh
210+
return await InnerTubeClient.getHomeWithContinuation(sectionLimit);
211+
}
202212

203-
// Try to get auth cookies for personalized content
204-
try {
205-
const ytAuthService = require('../Utils/YouTubeAuthService').default;
206-
if (ytAuthService.isAuth()) {
207-
authCookies = await ytAuthService.getCookies();
208-
}
209-
} catch (e) {}
213+
try {
214+
const cachedResult = await getCachedData(
215+
HOME_FEED_CACHE_KEY,
216+
async () => {
217+
// Fetch fresh data and wrap in success object for getCachedData
218+
const data = await InnerTubeClient.getHomeWithContinuation(sectionLimit);
219+
return { sections: data, success: true };
220+
},
221+
HOME_FEED_CACHE_TTL_MINUTES,
222+
CACHE_GROUPS.HOME,
223+
false // forceRefresh handled above
224+
);
210225

211-
// Get user's language and country preference from settings
212-
// Note: Language affects UI text, songs are based on listening HISTORY (visitorData)
213-
// Use an account with listening history for personalized recommendations
214-
let userLanguage = 'SYSTEM_DEFAULT';
215-
let userCountry = 'SYSTEM_DEFAULT';
216-
try {
217-
const AsyncStorage =
218-
require('@react-native-async-storage/async-storage').default;
219-
const storedLang = await AsyncStorage.getItem('ytmusic_language');
220-
const storedCountry = await AsyncStorage.getItem('ytmusic_country');
221-
if (storedLang) {
222-
userLanguage = storedLang;
223-
}
224-
if (storedCountry) {
225-
userCountry = storedCountry;
226-
}
227-
} catch (e) {}
226+
// getCachedData returns the data from fetchFunction directly on cache miss
227+
// On cache hit, it returns the cached data
228+
if (cachedResult && Array.isArray(cachedResult)) {
229+
return cachedResult;
230+
}
231+
if (cachedResult?.sections && Array.isArray(cachedResult.sections)) {
232+
return cachedResult.sections;
233+
}
234+
// Fallback to fresh fetch
235+
return await InnerTubeClient.getHomeWithContinuation(sectionLimit);
236+
} catch (error) {
237+
console.warn('YTMusic home cache error, fetching fresh:', error.message);
238+
return await InnerTubeClient.getHomeWithContinuation(sectionLimit);
239+
}
240+
}
228241

229-
// Initial request with user's language preference
230-
const data = await this.request(
242+
/**
243+
* Internal method - does the actual API fetching with continuation
244+
* @param {number} sectionLimit - Maximum number of sections to fetch
245+
*/
246+
static async getHomeWithContinuation(sectionLimit = 20) {
247+
let authCookies = null;
248+
249+
// Try to get auth cookies for personalized content
250+
try {
251+
const ytAuthService = require('../Utils/YouTubeAuthService').default;
252+
if (ytAuthService.isAuth()) {
253+
authCookies = await ytAuthService.getCookies();
254+
}
255+
} catch (e) {}
256+
257+
// Get user's language and country preference from settings
258+
// Note: Language affects UI text, songs are based on listening HISTORY (visitorData)
259+
// Use an account with listening history for personalized recommendations
260+
let userLanguage = 'SYSTEM_DEFAULT';
261+
let userCountry = 'SYSTEM_DEFAULT';
262+
try {
263+
const AsyncStorage =
264+
require('@react-native-async-storage/async-storage').default;
265+
const storedLang = await AsyncStorage.getItem('ytmusic_language');
266+
const storedCountry = await AsyncStorage.getItem('ytmusic_country');
267+
if (storedLang) {
268+
userLanguage = storedLang;
269+
}
270+
if (storedCountry) {
271+
userCountry = storedCountry;
272+
}
273+
} catch (e) {}
274+
275+
// Initial request with user's language preference
276+
const data = await this.request(
277+
'browse',
278+
{ browseId: 'FEmusic_home' },
279+
userCountry,
280+
authCookies,
281+
userLanguage
282+
);
283+
284+
// Parse initial sections, chips, and continuation token
285+
let { sections, chips, continuation } =
286+
this.parseHomeWithContinuation(data);
287+
let allSections = [...sections];
288+
const seenTitles = new Set(sections.map((s) => s.title));
289+
290+
// 1. Follow continuations iteratively (Main Home Feed)
291+
let continuationCount = 0;
292+
const MAX_CONTINUATIONS = 5;
293+
294+
while (
295+
continuation &&
296+
allSections.length < sectionLimit &&
297+
continuationCount < MAX_CONTINUATIONS
298+
) {
299+
const contData = await this.request(
231300
'browse',
232-
{ browseId: 'FEmusic_home' },
301+
{ continuation },
233302
userCountry,
234303
authCookies,
235304
userLanguage
236305
);
306+
const contResult = this.parseHomeContinuation(contData);
237307

238-
// Parse initial sections, chips, and continuation token
239-
let { sections, chips, continuation } =
240-
this.parseHomeWithContinuation(data);
241-
let allSections = [...sections];
242-
const seenTitles = new Set(sections.map((s) => s.title));
243-
244-
// 1. Follow continuations iteratively (Main Home Feed)
245-
let continuationCount = 0;
246-
const MAX_CONTINUATIONS = 5;
247-
248-
while (
249-
continuation &&
250-
allSections.length < sectionLimit &&
251-
continuationCount < MAX_CONTINUATIONS
252-
) {
253-
const contData = await this.request(
254-
'browse',
255-
{ continuation },
256-
userCountry,
257-
authCookies,
258-
userLanguage
259-
);
260-
const contResult = this.parseHomeContinuation(contData);
308+
let addedInThisCont = 0;
309+
contResult.sections.forEach((section) => {
310+
if (section.title && !seenTitles.has(section.title)) {
311+
seenTitles.add(section.title);
312+
allSections.push(section);
313+
addedInThisCont++;
314+
}
315+
});
316+
continuation = contResult.continuation;
317+
continuationCount++;
261318

262-
let addedInThisCont = 0;
263-
contResult.sections.forEach((section) => {
264-
if (section.title && !seenTitles.has(section.title)) {
265-
seenTitles.add(section.title);
266-
allSections.push(section);
267-
addedInThisCont++;
268-
}
269-
});
270-
continuation = contResult.continuation;
271-
continuationCount++;
319+
if (addedInThisCont === 0) {
320+
break;
321+
} // Stop if no new sections found
322+
}
323+
324+
// 2. Fetch from chips (additional variety like OuterTune)
325+
if (chips && chips.length > 0 && allSections.length < sectionLimit) {
326+
const chipsToFetch = [];
272327

273-
if (addedInThisCont === 0) {
274-
break;
275-
} // Stop if no new sections found
328+
// Prioritize the "Music" chip if found (contains personalized "Albums for you")
329+
const musicChip = chips.find((c) =>
330+
c.title.toLowerCase().includes('music')
331+
);
332+
if (musicChip) {
333+
chipsToFetch.push(musicChip);
276334
}
277335

278-
// 2. Fetch from chips (additional variety like OuterTune)
279-
if (chips && chips.length > 0 && allSections.length < sectionLimit) {
280-
const chipsToFetch = [];
336+
// Add other chips up to limit
337+
chips.forEach((c) => {
338+
if (c !== musicChip && chipsToFetch.length < 8) {
339+
chipsToFetch.push(c);
340+
}
341+
});
281342

282-
// Prioritize the "Music" chip if found (contains personalized "Albums for you")
283-
const musicChip = chips.find((c) =>
284-
c.title.toLowerCase().includes('music')
285-
);
286-
if (musicChip) {
287-
chipsToFetch.push(musicChip);
343+
const chipPromises = chipsToFetch.map(async (chip, idx) => {
344+
if (!chip.params) {
345+
return [];
288346
}
289347

290-
// Add other chips up to limit
291-
chips.forEach((c) => {
292-
if (c !== musicChip && chipsToFetch.length < 8) {
293-
chipsToFetch.push(c);
294-
}
295-
});
348+
try {
349+
const chipData = await this.request(
350+
'browse',
351+
{
352+
browseId: 'FEmusic_home',
353+
params: chip.params,
354+
},
355+
userCountry,
356+
authCookies,
357+
userLanguage
358+
);
296359

297-
const chipPromises = chipsToFetch.map(async (chip, idx) => {
298-
if (!chip.params) {
299-
return [];
300-
}
360+
const chipResult = this.parseHomeWithContinuation(chipData);
361+
return chipResult.sections;
362+
} catch (e) {
363+
return [];
364+
}
365+
});
301366

302-
try {
303-
const chipData = await this.request(
304-
'browse',
305-
{
306-
browseId: 'FEmusic_home',
307-
params: chip.params,
308-
},
309-
userCountry,
310-
authCookies,
311-
userLanguage
312-
);
367+
const chipResultsArr = await Promise.all(chipPromises);
313368

314-
const chipResult = this.parseHomeWithContinuation(chipData);
315-
return chipResult.sections;
316-
} catch (e) {
317-
return [];
369+
chipResultsArr.forEach((chipSections) => {
370+
chipSections.forEach((section) => {
371+
if (section.title && !seenTitles.has(section.title)) {
372+
seenTitles.add(section.title);
373+
allSections.push(section);
318374
}
319375
});
320-
321-
const chipResultsArr = await Promise.all(chipPromises);
322-
323-
chipResultsArr.forEach((chipSections) => {
324-
chipSections.forEach((section) => {
325-
if (section.title && !seenTitles.has(section.title)) {
326-
seenTitles.add(section.title);
327-
allSections.push(section);
328-
}
329-
});
330-
});
331-
}
332-
return allSections;
376+
});
333377
}
378+
return allSections;
379+
}
334380

335381
/**
336382
* Get Search Results

0 commit comments

Comments
 (0)