✨ Improve playlists feature
- 'playlist item' -> 'playlist media' - improve search - handle multiple matching media
This commit is contained in:
parent
d8ee08f7bb
commit
7006d52b6f
1 changed files with 34 additions and 28 deletions
58
main.js
58
main.js
|
@ -51,13 +51,15 @@ const
|
|||
}
|
||||
},
|
||||
setConfig = async (id, config) => await writeFile(`./data/${id}.json`, JSON.stringify(config)),
|
||||
parseMediaPath = path => {
|
||||
const title = path
|
||||
.slice(path.lastIndexOf('/') + 1, path.lastIndexOf('.'))
|
||||
parseMediaUrl = url => {
|
||||
const
|
||||
pathname = decodeURI(new URL(url).pathname),
|
||||
title = pathname
|
||||
.slice(pathname.lastIndexOf('/') + 1, pathname.lastIndexOf('.'))
|
||||
.replace(/[\s\-._()&+\[\],]/g, ' ')
|
||||
.replace(/\s+/g, ' ');
|
||||
return {
|
||||
path,
|
||||
url,
|
||||
title,
|
||||
keywords: title.toLowerCase().split(' ')
|
||||
};
|
||||
|
@ -145,8 +147,8 @@ const
|
|||
.alias('pl')
|
||||
.description('Manage playlists & play on MPV')
|
||||
.argument('[name]', 'Playlist name')
|
||||
.argument('[item]', 'Playlist item index/name/partial name')
|
||||
.action(async (name, item) => {
|
||||
.argument('[media]', 'Playlist media index/title/partial title')
|
||||
.action(async (name, media) => {
|
||||
const
|
||||
config = await getConfig(authorID) || {},
|
||||
newPlaylistUrl = attachments[0]?.url;
|
||||
|
@ -184,31 +186,35 @@ const
|
|||
if(/\.m3u8?$/i.test(playlistPathname)){
|
||||
if(!rawPlaylistData.startsWith('#EXTM3U'))
|
||||
rawPlaylistData = `#EXTM3U\n${rawPlaylistData}`;
|
||||
playlistItems = M3uParser.parse(rawPlaylistData).medias.map(item => ({
|
||||
url: item['location'],
|
||||
title: item['name'] || new URL(item['location']).pathname.split('/').slice(-1)[0]
|
||||
}));
|
||||
playlistItems = M3uParser.parse(rawPlaylistData).medias.map(item => parseMediaUrl(item['location']));
|
||||
}
|
||||
if(/\.xspf?$/i.test(playlistPathname)){
|
||||
playlistItems = parseXspf(rawPlaylistData)['playlist']['tracks'].map(item => ({
|
||||
url: item['location'],
|
||||
title: item['title'] || new URL(item['location']).pathname.split('/').slice(-1)[0]
|
||||
}));
|
||||
}
|
||||
if(!item)
|
||||
if(/\.xspf?$/i.test(playlistPathname))
|
||||
playlistItems = parseXspf(rawPlaylistData)['playlist']['tracks'].map(item => parseMediaUrl(item['location']));
|
||||
if(!media)
|
||||
return response = {
|
||||
output: outdent `
|
||||
📀 ${playlist.name}
|
||||
${playlistItems.map((item, index) => `${index + 1}. \`${item.title}\``).join('\n')}
|
||||
`
|
||||
};
|
||||
const playlistItem = /^\d+$/.test(item)
|
||||
? playlistItems[parseInt(item) - 1]
|
||||
: playlistItems.find(({ title }) => title.toLowerCase().includes(item.toLowerCase()));
|
||||
if(!playlistItem)
|
||||
return response = { embed: { title: `❌ Item not found` } };
|
||||
await adb(`am start -a android.intent.action.VIEW -d ${playlistItem.url} -t video/any is.xyz.mpv`);
|
||||
return response = { embed: { title: `▶️ \`${playlistItem.title}\`` } };
|
||||
const
|
||||
isIndex = /^\d+$/.test(media),
|
||||
keywords = isIndex ? undefined : media.toLowerCase().split(' '),
|
||||
matchingPlaylistItems = isIndex
|
||||
? [playlistItems[parseInt(media) - 1]]
|
||||
: playlistItems.filter(item => keywords.every(keyword => item.keywords.includes(keyword)));
|
||||
if(matchingPlaylistItems.length === 0)
|
||||
return response = { embed: { title: `❌ Media not found` } };
|
||||
if(matchingPlaylistItems.length > 1)
|
||||
return response = {
|
||||
output: outdent `
|
||||
🔎 Multiple media found :
|
||||
${matchingPlaylistItems.map(item => `${playlistItems.indexOf(item) + 1}\\. \`${item.title}\``).join('\n')}
|
||||
`
|
||||
};
|
||||
const [matchingPlaylistItem] = matchingPlaylistItems;
|
||||
await adb(`am start -a android.intent.action.VIEW -d ${matchingPlaylistItem.url} -t video/any is.xyz.mpv`);
|
||||
return response = { embed: { title: `▶️ \`${matchingPlaylistItem.title}\`` } };
|
||||
});
|
||||
program
|
||||
.command('playlist.rm')
|
||||
|
@ -232,7 +238,7 @@ const
|
|||
.description('List & play local media')
|
||||
.argument('[media]', 'Media title/partial title')
|
||||
.action(async title => {
|
||||
const mediaList = (await adb(`find ${localMediaRootPath} -iname "*.mkv" -o -iname "*.mp4"`)).split('\n').map(parseMediaPath);
|
||||
const mediaList = (await adb(`find ${localMediaRootPath} -iname "*.mkv" -o -iname "*.mp4"`)).split('\n').map(path => parseMediaUrl(`file://${path}`));
|
||||
if(!title)
|
||||
return response = {
|
||||
output: outdent `
|
||||
|
@ -253,7 +259,7 @@ const
|
|||
`
|
||||
};
|
||||
const [matchingMedia] = matchingMediaList;
|
||||
await adb(`am start -a android.intent.action.VIEW -n com.android.gallery3d/.app.MovieActivity -d "${matchingMedia.path}" -e MediaPlayerType 2`);
|
||||
await adb(`am start -a android.intent.action.VIEW -n com.android.gallery3d/.app.MovieActivity -d "${matchingMedia.url}" -e MediaPlayerType 2`);
|
||||
return response = { embed: { title: `▶️ \`${matchingMedia.title}\`` } };
|
||||
});
|
||||
program
|
||||
|
|
Loading…
Reference in a new issue