aboutsummaryrefslogtreecommitdiffstats
path: root/src/js/html5.js
blob: 3818a4413ac4be6a4700c3236c51b2015162b452 (plain)
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
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// ==========================================================================
// Plyr HTML5 helpers
// ==========================================================================

import support from './support';
import utils from './utils';

const html5 = {
    getSources() {
        if (!this.isHTML5) {
            return null;
        }

        return this.media.querySelectorAll('source');
    },

    // Get quality levels
    getQualityOptions() {
        if (!this.isHTML5) {
            return null;
        }

        // Get sources
        const sources = html5.getSources.call(this);

        if (utils.is.empty(sources)) {
            return null;
        }

        // Get <source> with size attribute
        const sizes = Array.from(sources).filter(source => !utils.is.empty(source.getAttribute('size')));

        // If none, bail
        if (utils.is.empty(sizes)) {
            return null;
        }

        // Reduce to unique list
        return utils.dedupe(sizes.map(source => Number(source.getAttribute('size'))));
    },

    extend() {
        if (!this.isHTML5) {
            return;
        }

        const player = this;

        // Quality
        Object.defineProperty(player.media, 'quality', {
            get() {
                // Get sources
                const sources = html5.getSources.call(player);

                if (utils.is.empty(sources)) {
                    return null;
                }

                const matches = Array.from(sources).filter(source => source.getAttribute('src') === player.source);

                if (utils.is.empty(matches)) {
                    return null;
                }

                return Number(matches[0].getAttribute('size'));
            },
            set(input) {
                // Get sources
                const sources = html5.getSources.call(player);

                if (utils.is.empty(sources)) {
                    return;
                }

                // Get matches for requested size
                const matches = Array.from(sources).filter(source => Number(source.getAttribute('size')) === input);

                // No matches for requested size
                if (utils.is.empty(matches)) {
                    return;
                }

                // Get supported sources
                const supported = matches.filter(source => support.mime.call(player, source.getAttribute('type')));

                // No supported sources
                if (utils.is.empty(supported)) {
                    return;
                }

                // Trigger change event
                utils.dispatchEvent.call(player, player.media, 'qualityrequested', false, {
                    quality: input,
                });

                // Get current state
                const { currentTime, playing } = player;

                // Set new source
                player.media.src = supported[0].getAttribute('src');

                // Load new source
                player.media.load();

                // Resume playing
                if (playing) {
                    player.play();
                }

                // Restore time
                player.currentTime = currentTime;

                // Trigger change event
                utils.dispatchEvent.call(player, player.media, 'qualitychange', false, {
                    quality: input,
                });
            },
        });
    },

    // Cancel current network requests
    // See https://github.com/sampotts/plyr/issues/174
    cancelRequests() {
        if (!this.isHTML5) {
            return;
        }

        // Remove child sources
        utils.removeElement(html5.getSources());

        // Set blank video src attribute
        // This is to prevent a MEDIA_ERR_SRC_NOT_SUPPORTED error
        // Info: http://stackoverflow.com/questions/32231579/how-to-properly-dispose-of-an-html5-video-and-close-socket-or-connection
        this.media.setAttribute('src', this.config.blankVideo);

        // Load the new empty source
        // This will cancel existing requests
        // See https://github.com/sampotts/plyr/issues/174
        this.media.load();

        // Debugging
        this.debug.log('Cancelled network requests');
    },
};

export default html5;