跳到主要内容

搜索

你可以回顾一下【搜索方法】,来熟悉一下我们这一小节要完成的搜索方法。

在freesound网站中,搜索的关键词和页码体现在url上,因此我们只需要请求不同的url,解析返回的html页面就好了。
freesound-page.png

请求url

插件入参的packages提供了一些预置的库,用法可以直接参考其对应的官方文档。

请求网络可以用axios库,这是一个前端很常用的网络请求库。

根据上述思路,我们写出如下search函数,它首先能完成请求对应的网址:

const axios = require('axios');

// 搜索方法
async function search(query, page, type) {
if(type === 'music') {// 我们能搜索的只有音乐,因此判断下类型
// 获取网站的html
const rawHtml = (await axios.get('https://freesound.org/search', {
q: query,
page
})).data
// TODO: 接下来解析html

}
}


module.exports = {
platform: 'FreeSound', // 插件名
version: '0.0.0', // 版本号
srcUrl: 'https://gitee.com/maotoumao/MusicFreePlugins/raw/master/freesound.js', // 更新链接;当在app更新插件后会自动用此地址的插件覆盖
cacheControl: 'no-store', // 我们可以直接解析出musicItem的结构,因此选取no-store就好了,当然也可以不写这个字段
search // 在这里写上search方法,此时插件就会出现在搜索结果页了,尽管到这一步搜索结果是空的
}


解析html

我们可以F12看一下整个页面的结构: freesound-result.png 可以看到,所有和这个音频相关的信息都记录在页面结构中。我们只需要做对应的解析就好了。

插件入参的packages中同时提供了cheerio库,它可以用类似jquery的语法快速解析html元素。用法可以参考其官方文档。我们可以写以下程序去解析相关的信息:

const axios = require('axios');
const cheerio = require('cheerio');

async function search(query, page, type) {
if(type === 'music') {// 我们能搜索的只有音乐,因此判断下类型
// 获取网站的html
const rawHtml = (await axios.get('https://freesound.org/search', {
q: query,
page
})).data
// 接下来解析html
const $ = cheerio.load(rawHtml);
// 存储搜索结果
const searchResults = [];
// 找到所有的音频元素
const audioElements = $('.sample_player_small');
// 解析每一个音频元素
audioElements.each((index, element) => {
// id
const id = $(element).attr('id');
// 音频名
const title = $(element).find('.sound_filename').children('a').attr('title');
// 封面
const artwork = $(element).find('.background').css('background-url');
// 作者
const artist = $(element).find('.sample_information').children('.user').text();
// 专辑名,这里就随便写个了,不写也没事
const album = '来自FreeSound的音频';
// 源mp3
const url = $(element).find('.metadata').children('.mp3_file').attr('href');
// 接下来拼装成musicItem格式,并拼接结果中
searchResults.push({
id,
title,
artist,
artwork,
album,
url
})
});
// 总页码
const totalPage = parseInt($('.pagination').children('.last-page').text().trim());
// 最后,按照search方法的返回结果格式返回就好了
return {
isEnd: page >= totalPage, // 当当前页码比总页码更多时,搜索结束
data: searchResults // 本页的搜索结果
}
}
// 其他类型不做处理,就搜索不到
}

module.exports = {
platform: 'FreeSound', // 插件名
version: '0.0.0', // 版本号
srcUrl: 'https://gitee.com/maotoumao/MusicFreePlugins/raw/master/freesound.js', // 更新链接;当在app更新插件后会自动用此地址的插件覆盖
cacheControl: 'no-store', // 我们可以直接解析出musicItem的结构,因此选取no-store就好了,当然也可以不写这个字段
search // 在这里写上search方法,此时插件就会出现在搜索结果页了,这一步已经有搜索结果了
}


插件安装

到这里,插件的搜索功能就差不多了。此时你可以尝试安装一下:

install.png

我们来试一下搜索,可以看到搜索的结果已经正常展示出来了:

search-result.png

需要注意:app不保证搜索结果不重复,暂时需要由插件保证搜索结果无重复项。

这时候,如果你点击搜索,发现音频竟然可以正常播放:

play-page.png

这是因为,我们缺省了获取音源的方法,缺省时会取歌曲的url字段作为音源。当然你也可以试试把搜索结果中的url改成别的字段,然后再定义getMediaSource方法就好了。如果按这种方式的话,可以参考以下完整代码如下:

完整代码

const axios = require('axios');
const cheerio = require('cheerio');

async function search(query, page, type) {
if(type === 'music') {// 我们能搜索的只有音乐,因此判断下类型
// 获取网站的html
const rawHtml = (await axios.get('https://freesound.org/search', {
q: query,
page
})).data

// 接下来解析html
const $ = cheerio.load(rawHtml);
// 存储搜索结果
const searchResults = [];
// 找到所有的音频元素
const audioElements = $('.sample_player_small');
// 解析每一个音频元素
audioElements.each((index, element) => {
// id
const id = $(element).attr('id');
// 音频名
const title = $(element).find('.sound_filename').children('a').attr('title');
// 封面
const artwork = $(element).find('.background').css('background-url');
// 作者
const artist = $(element).find('.sample_information').children('.user').text();
// 专辑名,这里就随便写个了,不写也没事
const album = '来自FreeSound的音频';
// 源mp3
const url = $(element).find('.metadata').children('.mp3_file').attr('href');
// 接下来拼装成musicItem格式,并拼接结果中
searchResults.push({
id,
title,
artist,
artwork,
album,
yourName: url
})
});
// 总页码
const totalPage = parseInt($('.pagination').children('.last-page').text().trim());

// 最后,按照search方法的返回结果格式返回就好了
return {
isEnd: page >= totalPage, // 当当前页码比总页码更多时,搜索结束
data: searchResults // 本页的搜索结果
}

}
}

function getMediaSource(musicItem) {
return {
url: musicItem.yourName
}
}

module.exports = {
platform: 'FreeSound', // 插件名
version: '0.0.0', // 版本号
srcUrl: 'https://gitee.com/maotoumao/MusicFreePlugins/raw/master/freesound.js', // 更新链接;当在app更新插件后会自动用此地址的插件覆盖
cacheControl: 'no-store', // 我们可以直接解析出musicItem的结构,因此选取no-store就好了,当然也可以不写这个字段
search, // 在这里写上search方法,此时插件就会出现在搜索结果页了
getMediaSource, // 由于搜索结果中没有了url字段,需要指定如何获取音源
}