Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
 
17
/**
18
 * Main class for plugin 'media_youtube'
19
 *
20
 * @package   media_youtube
21
 * @copyright 2016 Marina Glancy
22
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 */
24
 
25
defined('MOODLE_INTERNAL') || die();
26
 
27
/**
28
 * Player that creates youtube embedding.
29
 *
30
 * @package   media_youtube
31
 * @author    2011 The Open University
32
 * @copyright 2016 Marina Glancy
33
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
34
 */
35
class media_youtube_plugin extends core_media_player_external {
36
    /**
37
     * Stores whether the playlist regex was matched last time when
38
     * {@link list_supported_urls()} was called
39
     * @var bool
40
     */
41
    protected $isplaylist = false;
42
 
43
    public function list_supported_urls(array $urls, array $options = array()) {
44
        // These only work with a SINGLE url (there is no fallback).
45
        if (count($urls) == 1) {
46
            $url = reset($urls);
47
 
48
            // Check against regex.
49
            if (preg_match($this->get_regex(), $url->out(false), $this->matches)) {
50
                $this->isplaylist = false;
51
                return array($url);
52
            }
53
 
54
            // Check against playlist regex.
55
            if (preg_match($this->get_regex_playlist(), $url->out(false), $this->matches)) {
56
                $this->isplaylist = true;
57
                return array($url);
58
            }
59
        }
60
 
61
        return array();
62
    }
63
 
64
    protected function embed_external(moodle_url $url, $name, $width, $height, $options) {
65
        global $OUTPUT;
66
        $nocookie = get_config('media_youtube', 'nocookie');
67
 
68
        $info = trim($name ?? '');
69
        if (empty($info) or strpos($info, 'http') === 0) {
70
            $info = get_string('pluginname', 'media_youtube');
71
        }
72
        $info = s($info);
73
 
74
        self::pick_video_size($width, $height);
75
 
76
        // Template context.
77
        $context = [
78
                'width' => $width,
79
                'height' => $height,
80
                'title' => $info
81
        ];
82
 
83
        if ($this->isplaylist) {
84
            $site = $this->matches[1];
85
            $playlist = $this->matches[3];
86
 
87
            $params = ['list' => $playlist];
88
 
89
            // Handle no cookie option.
90
            if (!$nocookie) {
91
                $embedurl = new moodle_url("https://$site/embed/videoseries", $params);
92
            } else {
93
                $embedurl = new moodle_url('https://www.youtube-nocookie.com/embed/videoseries', $params );
94
            }
95
            $context['embedurl'] = $embedurl->out(false);
96
 
97
            // Return the rendered template.
98
            return $OUTPUT->render_from_template('media_youtube/embed', $context);
99
 
100
        } else {
101
            $videoid = end($this->matches);
102
            $params = [];
103
            $start = self::get_start_time($url);
104
            if ($start > 0) {
105
                $params['start'] = $start;
106
            }
107
 
108
            $listid = $url->param('list');
109
            // Check for non-empty but valid playlist ID.
110
            if (!empty($listid) && !preg_match('/[^a-zA-Z0-9\-_]/', $listid)) {
111
                // This video is part of a playlist, and we want to embed it as such.
112
                $params['list'] = $listid;
113
            }
114
 
115
            // Add parameters to object to be passed to the mustache template.
116
            $params['rel'] = 0;
117
            $params['wmode'] = 'transparent';
118
 
119
            // Handle no cookie option.
120
            if (!$nocookie) {
121
                $embedurl = new moodle_url('https://www.youtube.com/embed/' . $videoid, $params );
122
            } else {
123
                $embedurl = new moodle_url('https://www.youtube-nocookie.com/embed/' . $videoid, $params );
124
            }
125
 
126
            $context['embedurl'] = $embedurl->out(false);
127
 
128
            // Return the rendered template.
129
            return $OUTPUT->render_from_template('media_youtube/embed', $context);
130
        }
131
 
132
    }
133
 
134
    /**
135
     * Check for start time parameter.  Note that it's in hours/mins/secs in the URL,
136
     * but the embedded player takes only a number of seconds as the "start" parameter.
137
     * @param moodle_url $url URL of video to be embedded.
138
     * @return int Number of seconds video should start at.
139
     */
140
    protected static function get_start_time($url) {
141
        $matches = array();
142
        $seconds = 0;
143
 
144
        $rawtime = $url->param('t');
145
        if (empty($rawtime)) {
146
            $rawtime = $url->param('start');
147
        }
148
 
149
        if (is_numeric($rawtime)) {
150
            // Start time already specified as a number of seconds; ensure it's an integer.
151
            $seconds = $rawtime;
152
        } else if (preg_match('/(\d+?h)?(\d+?m)?(\d+?s)?/i', $rawtime ?? '', $matches)) {
153
            // Convert into a raw number of seconds, as that's all embedded players accept.
154
            for ($i = 1; $i < count($matches); $i++) {
155
                if (empty($matches[$i])) {
156
                    continue;
157
                }
158
                $part = str_split($matches[$i], strlen($matches[$i]) - 1);
159
                switch ($part[1]) {
160
                    case 'h':
161
                        $seconds += 3600 * $part[0];
162
                        break;
163
                    case 'm':
164
                        $seconds += 60 * $part[0];
165
                        break;
166
                    default:
167
                        $seconds += $part[0];
168
                }
169
            }
170
        }
171
 
172
        return intval($seconds);
173
    }
174
 
175
    /**
176
     * Returns regular expression used to match URLs for single youtube video
177
     * @return string PHP regular expression e.g. '~^https?://example.org/~'
178
     */
179
    protected function get_regex() {
180
        // Regex for standard youtube link.
181
        $link = '(youtube(-nocookie)?\.com/(?:watch\?v=|v/))';
182
        // Regex for shortened youtube link.
183
        $shortlink = '((youtu|y2u)\.be/)';
184
 
185
        // Initial part of link.
186
        $start = '~^https?://((www|m)\.)?(' . $link . '|' . $shortlink . ')';
187
        // Middle bit: Video key value.
188
        $middle = '([a-z0-9\-_]+)';
189
        return $start . $middle . core_media_player_external::END_LINK_REGEX_PART;
190
    }
191
 
192
    /**
193
     * Returns regular expression used to match URLs for youtube playlist
194
     * @return string PHP regular expression e.g. '~^https?://example.org/~'
195
     */
196
    protected function get_regex_playlist() {
197
        // Initial part of link.
198
        $start = '~^https?://(www\.youtube(-nocookie)?\.com)/';
199
        // Middle bit: either view_play_list?p= or p/ (doesn't work on youtube) or playlist?list=.
200
        $middle = '(?:view_play_list\?p=|p/|playlist\?list=)([a-z0-9\-_]+)';
201
        return $start . $middle . core_media_player_external::END_LINK_REGEX_PART;
202
    }
203
 
204
    public function get_embeddable_markers() {
205
        return array('youtube.com', 'youtube-nocookie.com', 'youtu.be', 'y2u.be');
206
    }
207
 
208
    /**
209
     * Default rank
210
     * @return int
211
     */
212
    public function get_rank() {
213
        return 1001;
214
    }
215
}