<?xml version="1.0" encoding="utf-8"?>
<parser delay="4500" crpj="true" referer="true" date="2020.10.13">
    <url><![CDATA[ximalaya\.com/.*?/\d+/(?<id>\d+)]]></url>
    <title><![CDATA["title":"([^"]+)"]]></title>
    <thumbnail><![CDATA["cover_url":"([^"]+)"]]></thumbnail>
    <duration><![CDATA["duration":([^,]+)]]></duration>
    <mediaUrl><![CDATA["play_path":"([^"]+)"]]></mediaUrl>
    <ckSign><![CDATA[1&_token]]></ckSign>
    <jsCode><![CDATA[
        try {
            var m = window.location.href.match(/\d+\/(\d+)/);
            if (m) {
                var trackId = parseInt(m[1]);
                var url = 'http://www.ximalaya.com/tracks/' + trackId + '.json';
                var data = window.external.getHtmlCode(url);
                var video_url = '';
                //audio
                var m = data.match(/\"play_path\":\"([^\"]+)/);
                if (m)
                    video_url = m[1];
                //video
                m = document.body.innerHTML.match(/<video[^>]+src=\"([^\"]+)/);
                //须得做如此转义，还原&符号
                if (m)
                    video_url = htmlDecode(m[1]);
                //vip
                if (!video_url)
                    video_url = getVideoUrl(trackId);
                //try...
                if (!video_url)
                    video_url = getVideoUrl(trackId);
                if (video_url)
                    video_url = '\"play_path\":\"' + video_url + '\"';
                //为&time转义计
                document.body.innerText = video_url + '$' + data;
            }

            function htmlDecode(s) {
                var span = document.createElement('span');
                span.innerHTML = s;
                return span.innerText || span.textContent;
            }

            function getVideoUrl(trackId) {
                var api_url = 'https://mpay.ximalaya.com/mobile/track/pay/' + trackId + '?device=pc&isBackend=true&_=' + Date.now();
                var data = window.external.getHtmlCode(api_url, window.location.href, 200);
                if (!data)
                    return '';
                var jo = JSON.parse(data);
                if (!jo.seed || !jo.fileId)
                    return '';

                var e = {}, t = {}, n = function(){};
                x(e, t, n);
                var fn = t.getEncryptedFileName(jo.seed, jo.fileId);
                var p = t.getEncryptedFileParams(jo.ep);
                p.duration = jo.duration;
                p = stringify(p);
                var domain = jo.domain.indexOf('audio.pay.xmcdn.com') > -1 ? 'https://vod.xmcdn.com' : jo.domain;
                if (domain.indexOf('http:') != -1)
                    domain = domain.replace('http:', 'https:');
                if (fn.indexOf('_preview') != -1)
                    fn = fn.replace(/_preview[^.]+/, '');
                return domain + '/download/' + jo.apiVersion + fn + '?' + p;
            }

            function stringify(p) {
                var e = [];
                for (var n in p)
                    if (p.hasOwnProperty(n)) {
                        var r = encodeURIComponent(p[n])
                          , o = encodeURIComponent(n);
                        e.push(''.concat(o, '=').concat(r))
                    }
                return e.join('&')
            }

            function x(e, t, n) {
                function o(e, t) {
                    return function(e) {
                        if (Array.isArray(e))
                            return e
                    }(e) || function(e, t) {
                        if (!(Symbol.iterator in Object(e) || '[object Arguments]' === Object.prototype.toString.call(e)))
                            return;
                        var n = []
                          , o = !0
                          , r = !1
                          , a = void 0;
                        try {
                            for (var i, u = e[Symbol.iterator](); !(o = (i = u.next()).done) && (n.push(i.value),
                            !t || n.length !== t); o = !0)
                                ;
                        } catch (e) {
                            r = !0,
                            a = e
                        } finally {
                            try {
                                o || null == u.return || u.return()
                            } finally {
                                if (r)
                                    throw a
                            }
                        }
                        return n
                    }(e, t) || function() {
                        throw new TypeError('Invalid attempt to destructure non-iterable instance')
                    }()
                }
                function r(e, t) {
                    for (var n, o = [], r = 0, a = '', i = 0; 256 > i; i++)
                        o[i] = i;
                    for (i = 0; 256 > i; i++)
                        r = (r + o[i] + e.charCodeAt(i % e.length)) % 256,
                        n = o[i],
                        o[i] = o[r],
                        o[r] = n;
                    for (var u = r = i = 0; u < t.length; u++)
                        r = (r + o[i = (i + 1) % 256]) % 256,
                        n = o[i],
                        o[i] = o[r],
                        o[r] = n,
                        a += String.fromCharCode(t.charCodeAt(u) ^ o[(o[i] + o[r]) % 256]);
                    return a
                }
                function a(e) {
                    this._randomSeed = e,
                    this.cg_hun()
                }
                Object.defineProperty(t, '__esModule', {
                    value: !0
                }),
                t.getEncryptedFileParams = t.getEncryptedFileName = void 0,
                a.prototype = {
                    cg_hun: function() {
                        this._cgStr = '';
                        var e = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/\\:._-1234567890'
                          , t = e.length
                          , n = 0;
                        for (n = 0; n < t; n++) {
                            var o = this.ran() * e.length
                              , r = parseInt(o);
                            this._cgStr += e.charAt(r),
                            e = e.split(e.charAt(r)).join('')
                        }
                    },
                    cg_fun: function(e) {
                        e = e.split('*');
                        var t = ''
                          , n = 0;
                        for (n = 0; n < e.length - 1; n++)
                            t += this._cgStr.charAt(e[n]);
                        return t
                    },
                    ran: function() {
                        return this._randomSeed = (211 * this._randomSeed + 30031) % 65536,
                        this._randomSeed / 65536
                    },
                    cg_decode: function(e) {
                        var t = ''
                          , n = 0;
                        for (n = 0; n < e.length; n++) {
                            var o = e.charAt(n)
                              , r = this._cgStr.indexOf(o);
                            -1 !== r && (t += r + '*')
                        }
                        return t
                    }
                };
                t.getEncryptedFileName = function(e, t) {
                    var n = new a(e).cg_fun(t);
                    return '/' === n[0] ? n : '/'.concat(n)
                }
                ;
                var i = 'g3utf1k6yxdwi0'
                  , u = [19, 1, 4, 7, 30, 14, 28, 8, 24, 17, 6, 35, 34, 16, 9, 10, 13, 22, 32, 29, 31, 21, 18, 3, 2, 23, 25, 27, 11, 20, 5, 15, 12, 0, 33, 26];
                t.getEncryptedFileParams = function(e) {
                    var t = o(r(function(e, t) {
                        for (var n = [], o = 0; o < e.length; o++) {
                            for (var r = 'a' <= e[o] && 'z' >= e[o] ? e[o].charCodeAt() - 97 : e[o].charCodeAt() - 48 + 26, a = 0; 36 > a; a++)
                                if (t[a] == r) {
                                    r = a;
                                    break
                                }
                            n[o] = 25 < r ? String.fromCharCode(r - 26 + 48) : String.fromCharCode(r + 97)
                        }
                        return n.join('')
                    }('d' + i + '9', u), function(e) {
                        if (!e)
                            return '';
                        var t, n, o, r, a, i = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1];
                        for (r = (e = e.toString()).length,
                        o = 0,
                        a = ''; o < r; ) {
                            do {
                                t = i[255 & e.charCodeAt(o++)]
                            } while (o < r && -1 == t);if (-1 == t)
                                break;
                            do {
                                n = i[255 & e.charCodeAt(o++)]
                            } while (o < r && -1 == n);if (-1 == n)
                                break;
                            a += String.fromCharCode(t << 2 | (48 & n) >> 4);
                            do {
                                if (61 == (t = 255 & e.charCodeAt(o++)))
                                    return a;
                                t = i[t]
                            } while (o < r && -1 == t);if (-1 == t)
                                break;
                            a += String.fromCharCode((15 & n) << 4 | (60 & t) >> 2);
                            do {
                                if (61 == (n = 255 & e.charCodeAt(o++)))
                                    return a;
                                n = i[n]
                            } while (o < r && -1 == n);if (-1 == n)
                                break;
                            a += String.fromCharCode((3 & t) << 6 | n)
                        }
                        return a
                    }(e)).split('-'), 4)
                      , n = t[0];
                    return {
                        sign: t[1],
                        buy_key: n,
                        token: t[2],
                        timestamp: t[3]
                    }
                }
            }
        }
        catch (ex) {
        }
    ]]></jsCode>
</parser>