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_html5video'
19
 *
20
 * @package   media_html5video
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 HTML5 <video> tag.
29
 *
30
 * @package   media_html5video
31
 * @copyright 2016 Marina Glancy
32
 * @author 2011 The Open University
33
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
34
 */
35
class media_html5video_plugin extends core_media_player_native {
36
    public function embed($urls, $name, $width, $height, $options) {
37
 
38
        if (array_key_exists(core_media_manager::OPTION_ORIGINAL_TEXT, $options) &&
39
            preg_match('/^<(video|audio)\b/i', $options[core_media_manager::OPTION_ORIGINAL_TEXT], $matches)) {
40
            // We already had media tag, do nothing here.
41
            return $options[core_media_manager::OPTION_ORIGINAL_TEXT];
42
        }
43
 
44
        // Special handling to make videos play on Android devices pre 2.3.
45
        // Note: I tested and 2.3.3 (in emulator) works without, is 533.1 webkit.
46
        $oldandroid = core_useragent::is_webkit_android() &&
47
            !core_useragent::check_webkit_android_version('533.1');
48
 
49
        // Build array of source tags.
50
        $sources = array();
51
        foreach ($urls as $url) {
52
            $mimetype = core_media_manager::instance()->get_mimetype($url);
53
            if ($mimetype === 'video/quicktime' && (core_useragent::is_chrome() || core_useragent::is_edge())) {
54
                // Set mimetype of quicktime videos to mp4 for Chrome/Edge browsers.
55
                $mimetype = 'video/mp4';
56
            }
57
            $source = html_writer::empty_tag('source', array('src' => $url, 'type' => $mimetype));
58
            if ($mimetype === 'video/mp4') {
59
                if ($oldandroid) {
60
                    // Old Android fails if you specify the type param.
61
                    $source = html_writer::empty_tag('source', array('src' => $url));
62
                }
63
 
64
                // Better add m4v as first source, it might be a bit more
65
                // compatible with problematic browsers.
66
                array_unshift($sources, $source);
67
            } else {
68
                $sources[] = $source;
69
            }
70
        }
71
 
72
        $sources = implode("\n", $sources);
73
        $title = $this->get_name($name, $urls);
74
        // Escape title but prevent double escaping.
75
        $title = s(preg_replace(['/&amp;/', '/&gt;/', '/&lt;/'], ['&', '>', '<'], $title));
76
 
77
        self::pick_video_size($width, $height);
78
        if (!$height) {
79
            // Let browser choose height automatically.
80
            $size = "width=\"$width\"";
81
        } else {
82
            $size = "width=\"$width\" height=\"$height\"";
83
        }
84
 
85
        $sillyscript = '';
86
        $idtag = '';
87
        if ($oldandroid) {
88
            // Old Android does not support 'controls' option.
89
            $id = 'core_media_html5v_' . md5(time() . '_' . rand());
90
            $idtag = 'id="' . $id . '"';
91
            $sillyscript = <<<OET
92
<script type="text/javascript">
93
document.getElementById('$id').addEventListener('click', function() {
94
    this.play();
95
}, false);
96
</script>
97
OET;
98
        }
99
 
100
        // We don't want fallback to another player because list_supported_urls() is already smart.
101
        // Otherwise we could end up with nested <video> tags. Fallback to link only.
102
        $fallback = self::LINKPLACEHOLDER;
103
        return <<<OET
104
<span class="mediaplugin mediaplugin_html5video">
105
<video $idtag controls="true" $size preload="metadata" title="$title">
106
    $sources
107
    $fallback
108
</video>
109
$sillyscript
110
</span>
111
OET;
112
    }
113
 
114
    public function get_supported_extensions() {
115
        global $CFG;
116
        require_once($CFG->libdir . '/filelib.php');
117
        return file_get_typegroup('extension', 'html_video');
118
    }
119
 
120
    public function list_supported_urls(array $urls, array $options = array()) {
121
        $extensions = $this->get_supported_extensions();
122
        $result = array();
123
        foreach ($urls as $url) {
124
            $ext = core_media_manager::instance()->get_extension($url);
125
            if (in_array('.' . $ext, $extensions) && core_useragent::supports_html5($ext)) {
126
                // Unfortunately html5 video does not handle fallback properly.
127
                // https://www.w3.org/Bugs/Public/show_bug.cgi?id=10975
128
                // That means we need to do browser detect and not use html5 on
129
                // browsers which do not support the given type, otherwise users
130
                // will not even see the fallback link.
131
                $result[] = $url;
132
            }
133
        }
134
        return $result;
135
    }
136
 
137
    /**
138
     * Utility function that sets width and height to defaults if not specified
139
     * as a parameter to the function (will be specified either if, (a) the calling
140
     * code passed it, or (b) the URL included it).
141
     * @param int $width Width passed to function (updated with final value)
142
     * @param int $height Height passed to function (updated with final value)
143
     */
144
    protected static function pick_video_size(&$width, &$height) {
145
        global $CFG;
146
        if (!$width) {
147
            $width = $CFG->media_default_width;
148
        }
149
    }
150
 
151
    /**
152
     * Default rank
153
     * @return int
154
     */
155
    public function get_rank() {
156
        return 50;
157
    }
158
}