<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://docs.moodle.org/dev/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Kabalin</id>
	<title>MoodleDocs - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://docs.moodle.org/dev/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Kabalin"/>
	<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/Special:Contributions/Kabalin"/>
	<updated>2026-06-04T08:19:28Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Moodle_Workplace_releases&amp;diff=64061</id>
		<title>Moodle Workplace releases</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Moodle_Workplace_releases&amp;diff=64061"/>
		<updated>2023-12-28T09:42:14Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: Release timestamps&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Workplace}}&lt;br /&gt;
This page lists all official releases of Moodle Workplace, grouped by branch in reverse chronological order.&lt;br /&gt;
==Release cycle==&lt;br /&gt;
Moodle Workplace is based on top of Moodle LMS. Moodle Workplace releases always follow the Moodle LMS releases. The minors are normally released the next day and the majors are normally released after three-four weeks.&lt;br /&gt;
&lt;br /&gt;
These are the target dates for releases. These dates may vary slightly due to unforeseen circumstances. When the Moodle LMS release is delayed, the Moodle Workplace release is delayed respectively. See also [https://moodledev.io/general/releases Moodle LMS Releases].&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; |&amp;lt;big&amp;gt;Release&amp;lt;/big&amp;gt;&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; style=&amp;quot;background-color:#b7d5e7;&amp;quot; |&amp;lt;big&amp;gt;Moodle Workplace&amp;lt;/big&amp;gt;&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; |&amp;lt;big&amp;gt;Moodle LMS&amp;lt;/big&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Release type&lt;br /&gt;
! Frequency&lt;br /&gt;
! style=&amp;quot;background-color:#b7d5e7;&amp;quot; | Release&lt;br /&gt;
! ! style=&amp;quot;background-color:#b7d5e7;&amp;quot; | Includes&lt;br /&gt;
! Release&lt;br /&gt;
! Includes&lt;br /&gt;
|-&lt;br /&gt;
| [[Process#Major_release_cycles|Major]] (eg. 3.x)&lt;br /&gt;
| 6 monthly&lt;br /&gt;
|3-4 weeks after Moodle LMS major&lt;br /&gt;
|New features, improvements and bug fixes (Moodle LMS and Workplace)&lt;br /&gt;
| April and October&lt;br /&gt;
|New features, Improvements and fixes&lt;br /&gt;
|-&lt;br /&gt;
|[[Process#Stable_maintenance_cycles|Minor]] (Point) (eg. 3.x.y)&lt;br /&gt;
| 2 monthly&lt;br /&gt;
|1 day after Moodle LMS minor&lt;br /&gt;
|Workplace new features, improvements and bug fixes and Moodle LMS fixes&lt;br /&gt;
| February, April, June, August, October and December&lt;br /&gt;
|Fixes based on the latest major release and never any significant new features or database changes&lt;br /&gt;
|}&lt;br /&gt;
Starting from 4.1 release, we package two Workplace versions in every release:&lt;br /&gt;
* &#039;&#039;&#039;Standard version&#039;&#039;&#039;: no new features in minor releases, this version is supported for bug fixes and security fixes while the corresponding version of LMS is supported&lt;br /&gt;
* &#039;&#039;&#039;Rolling version&#039;&#039;&#039;: features are added continuously up until the new major release of LMS, after that it has bug fixes for four more months and then support stops completely (which is approximately 3 months after the next Workplace major release).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:workplace releases timeline.png|frameless|1100x1100px]]&lt;br /&gt;
=== End-of-life dates for currently supported releases ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
!Version&lt;br /&gt;
!Latest Release&lt;br /&gt;
!Improvements and new features&lt;br /&gt;
!Bug fixes&lt;br /&gt;
!Security fixes&lt;br /&gt;
|-&lt;br /&gt;
|4.3 Rolling&lt;br /&gt;
|28 December 2023&lt;br /&gt;
|22 April 2024&lt;br /&gt;
|22 August 2024&lt;br /&gt;
|22 August 2024&lt;br /&gt;
|-&lt;br /&gt;
|4.3&lt;br /&gt;
|28 December 2023&lt;br /&gt;
|14 October 2024&lt;br /&gt;
|14 April 2025&lt;br /&gt;
|14 April 2025&lt;br /&gt;
|-&lt;br /&gt;
|4.2 Rolling&lt;br /&gt;
|28 December 2023&lt;br /&gt;
|&lt;br /&gt;
|13 February 2024&lt;br /&gt;
|13 February 2024&lt;br /&gt;
|-&lt;br /&gt;
|4.2&lt;br /&gt;
|28 December 2023&lt;br /&gt;
|&lt;br /&gt;
|23 April 2024&lt;br /&gt;
|8 October 2024&lt;br /&gt;
|-&lt;br /&gt;
|4.1 LTS&lt;br /&gt;
|28 December 2023&lt;br /&gt;
|&lt;br /&gt;
|12 December 2023&lt;br /&gt;
|9 December 2025&lt;br /&gt;
|-&lt;br /&gt;
|4.0&lt;br /&gt;
|13 June 2023&lt;br /&gt;
|&lt;br /&gt;
|12 December 2023 (only critical)&lt;br /&gt;
|12 December 2023&lt;br /&gt;
|-&lt;br /&gt;
|3.11&lt;br /&gt;
|13 June 2023&lt;br /&gt;
|&lt;br /&gt;
|12 December 2023 (only critical)&lt;br /&gt;
|12 December 2023&lt;br /&gt;
|}&lt;br /&gt;
==Moodle Workplace 4.3 Rolling==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
! Date&lt;br /&gt;
! Version number&lt;br /&gt;
! Moodle LMS release notes&lt;br /&gt;
! Moodle Workplace release notes&lt;br /&gt;
|-&lt;br /&gt;
! Moodle Workplace 4.3&lt;br /&gt;
| 9 Nov 2023&lt;br /&gt;
| 2023110900&lt;br /&gt;
| [https://moodledev.io/general/releases/4.3 Moodle LMS 4.3]&lt;br /&gt;
| [https://docs.moodle.org/403/en/Moodle_Workplace_rolling_release_notes Moodle Workplace 4.3 rolling]&lt;br /&gt;
|-&lt;br /&gt;
! Moodle Workplace 4.3.1&lt;br /&gt;
| 12 December 2023&lt;br /&gt;
| 2023121200&lt;br /&gt;
|[https://moodledev.io/general/releases/4.3/4.3.1 Moodle LMS 4.3.1]&lt;br /&gt;
|[https://docs.moodle.org/403/en/Moodle_Workplace_rolling_release_notes#4.3.1_rolling Moodle Workplace 4.3.1 rolling]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 4.3.2&lt;br /&gt;
|28 December 2023&lt;br /&gt;
|2023122800&lt;br /&gt;
|[https://moodledev.io/general/releases/4.3/4.3.2 Moodle LMS 4.3.2]&lt;br /&gt;
|[https://docs.moodle.org/403/en/Moodle_Workplace_rolling_release_notes#4.3.2_rolling Moodle Workplace 4.3.2 rolling]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
 Improvements and new features will end 22 April 2024&lt;br /&gt;
 Bug fixes and security fixes will end 22 August 2024&lt;br /&gt;
==Moodle Workplace 4.3==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
! Date&lt;br /&gt;
! Version number&lt;br /&gt;
! Moodle LMS release notes&lt;br /&gt;
! Moodle Workplace release notes&lt;br /&gt;
|-&lt;br /&gt;
! Moodle Workplace 4.3&lt;br /&gt;
| 9 Nov 2023&lt;br /&gt;
| 2023110900&lt;br /&gt;
| [https://moodledev.io/general/releases/4.3 Moodle LMS 4.3]&lt;br /&gt;
| [https://docs.moodle.org/403/en/Moodle_Workplace_release_notes Moodle Workplace 4.3]&lt;br /&gt;
|-&lt;br /&gt;
! Moodle Workplace 4.3.1&lt;br /&gt;
| 12 December 2023&lt;br /&gt;
| 2023110910&lt;br /&gt;
|[https://moodledev.io/general/releases/4.3/4.3.1 Moodle LMS 4.3.1]&lt;br /&gt;
|[https://docs.moodle.org/403/en/Moodle_Workplace_release_notes#4.3.1 Moodle Workplace 4.3.1]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 4.3.2&lt;br /&gt;
|28 December 2023&lt;br /&gt;
|2023110920&lt;br /&gt;
|[https://moodledev.io/general/releases/4.3/4.3.2 Moodle LMS 4.3.2]&lt;br /&gt;
|[https://docs.moodle.org/403/en/Moodle_Workplace_release_notes#4.3.2 Moodle Workplace 4.3.2]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes will end 8 October 2024&lt;br /&gt;
 Bug fixes for security issues will end 22 April 2025&lt;br /&gt;
==Moodle Workplace 4.2 Rolling==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
! Date&lt;br /&gt;
! Version number&lt;br /&gt;
! Moodle LMS release notes&lt;br /&gt;
! Moodle Workplace release notes&lt;br /&gt;
|-&lt;br /&gt;
! Moodle Workplace 4.2&lt;br /&gt;
| 30 May 2023&lt;br /&gt;
| 2023053000&lt;br /&gt;
| [https://moodledev.io/general/releases/4.2 Moodle LMS 4.2]&lt;br /&gt;
| [https://docs.moodle.org/402/en/Moodle_Workplace_rolling_release_notes Moodle Workplace 4.2 rolling]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 4.2.1&lt;br /&gt;
|13 June 2023&lt;br /&gt;
|2023061300&lt;br /&gt;
|[https://moodledev.io/general/releases/4.2/4.2.1 Moodle LMS 4.2.1]&lt;br /&gt;
|[https://docs.moodle.org/402/en/Moodle_Workplace_rolling_release_notes#4.2.1 Moodle Workplace 4.2.1 rolling]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 4.2.2&lt;br /&gt;
|22 August 2023&lt;br /&gt;
|2023082200&lt;br /&gt;
|[https://moodledev.io/general/releases/4.2/4.2.2 Moodle LMS 4.2.2]&lt;br /&gt;
|[https://docs.moodle.org/402/en/Moodle_Workplace_rolling_release_notes#4.2.2_rolling Moodle Workplace 4.2.2 rolling]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 4.2.3&lt;br /&gt;
|10 October 2023&lt;br /&gt;
|2023101000&lt;br /&gt;
|[https://moodledev.io/general/releases/4.2/4.2.3 Moodle LMS 4.2.3]&lt;br /&gt;
|[https://docs.moodle.org/402/en/Moodle_Workplace_rolling_release_notes#4.2.3_rolling Moodle Workplace 4.2.3 rolling]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 4.2.4&lt;br /&gt;
|12 December 2023&lt;br /&gt;
|2023101010&lt;br /&gt;
|[https://moodledev.io/general/releases/4.2/4.2.4 Moodle LMS 4.2.4]&lt;br /&gt;
|[https://docs.moodle.org/402/en/Moodle_Workplace_rolling_release_notes#4.2.4_rolling Moodle Workplace 4.2.4 rolling]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 4.2.5&lt;br /&gt;
|28 December 2023&lt;br /&gt;
|2023101020&lt;br /&gt;
|[https://moodledev.io/general/releases/4.2/4.2.5 Moodle LMS 4.2.5]&lt;br /&gt;
|[https://docs.moodle.org/402/en/Moodle_Workplace_rolling_release_notes#4.2.5_rolling Moodle Workplace 4.2.5 rolling]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
 Improvements and new features ended 10 October 2023&lt;br /&gt;
 Bug fixes and security fixes will end 13 February 2024&lt;br /&gt;
==Moodle Workplace 4.2==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
! Date&lt;br /&gt;
! Version number&lt;br /&gt;
! Moodle LMS release notes&lt;br /&gt;
! Moodle Workplace release notes&lt;br /&gt;
|-&lt;br /&gt;
! Moodle Workplace 4.2&lt;br /&gt;
| 30 May 2023&lt;br /&gt;
| 2023053000&lt;br /&gt;
| [https://moodledev.io/general/releases/4.2 Moodle LMS 4.2]&lt;br /&gt;
| [https://docs.moodle.org/402/en/Moodle_Workplace_release_notes Moodle Workplace 4.2]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 4.2.1&lt;br /&gt;
|13 June 2023&lt;br /&gt;
|2023053010&lt;br /&gt;
|[https://moodledev.io/general/releases/4.2/4.2.1 Moodle LMS 4.2.1]&lt;br /&gt;
|[https://docs.moodle.org/402/en/Moodle_Workplace_release_notes#4.2.1 Moodle Workplace 4.2.1]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 4.2.2&lt;br /&gt;
|22 August 2023&lt;br /&gt;
|2023053020&lt;br /&gt;
|[https://moodledev.io/general/releases/4.2/4.2.2 Moodle LMS 4.2.2]&lt;br /&gt;
|[https://docs.moodle.org/402/en/Moodle_Workplace_release_notes#4.2.2 Moodle Workplace 4.2.2]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 4.2.3&lt;br /&gt;
|10 October 2023&lt;br /&gt;
|2023053030&lt;br /&gt;
|[https://moodledev.io/general/releases/4.2/4.2.3 Moodle LMS 4.2.3]&lt;br /&gt;
|[https://docs.moodle.org/402/en/Moodle_Workplace_release_notes#4.2.3 Moodle Workplace 4.2.3]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 4.2.4&lt;br /&gt;
|12 December 2023&lt;br /&gt;
|2023053040&lt;br /&gt;
|[https://moodledev.io/general/releases/4.2/4.2.4 Moodle LMS 4.2.4]&lt;br /&gt;
|[https://docs.moodle.org/402/en/Moodle_Workplace_release_notes#4.2.4 Moodle Workplace 4.2.4]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 4.2.5&lt;br /&gt;
|28 December 2023&lt;br /&gt;
|2023053050&lt;br /&gt;
|[https://moodledev.io/general/releases/4.2/4.2.5 Moodle LMS 4.2.5]&lt;br /&gt;
|[https://docs.moodle.org/402/en/Moodle_Workplace_release_notes#4.2.5 Moodle Workplace 4.2.5]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes will end 23 April 2024&lt;br /&gt;
 Bug fixes for security issues will end 8 October 2024&lt;br /&gt;
==Moodle Workplace 4.1 Rolling==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
! Date&lt;br /&gt;
! Version number&lt;br /&gt;
! Moodle LMS release notes&lt;br /&gt;
! Moodle Workplace release notes&lt;br /&gt;
|-&lt;br /&gt;
! Moodle Workplace 4.1&lt;br /&gt;
| 11 January 2023&lt;br /&gt;
| 2023110100&lt;br /&gt;
| [https://moodledev.io/general/releases/4.1 Moodle LMS 4.1]&lt;br /&gt;
| [[Moodle Workplace 4.1 release notes|Moodle Workplace 4.1 rolling]]&lt;br /&gt;
|-&lt;br /&gt;
! Moodle Workplace 4.1.1&lt;br /&gt;
| 17 January 2023&lt;br /&gt;
| 2023011700&lt;br /&gt;
| [https://moodledev.io/general/releases/4.1/4.1.1 Moodle LMS 4.1.1]&lt;br /&gt;
| [[Moodle Workplace 4.1 release notes#4.1.1|Moodle Workplace 4.1.1 rolling]]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 4.1.2&lt;br /&gt;
|14 March 2023&lt;br /&gt;
|2023031400&lt;br /&gt;
|[https://moodledev.io/general/releases/4.1/4.1.2 Moodle LMS 4.1.2]&lt;br /&gt;
|[[Moodle Workplace 4.1 release notes#4.1.2|Moodle Workplace 4.1.2 rolling]]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 4.1.3&lt;br /&gt;
|25 April 2023&lt;br /&gt;
|2023042500&lt;br /&gt;
|[https://moodledev.io/general/releases/4.1/4.1.3 Moodle LMS 4.1.3]&lt;br /&gt;
|[[Moodle Workplace 4.1 release notes#4.1.3|Moodle Workplace 4.1.3 rolling]]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 4.1.4&lt;br /&gt;
|13 June 2023&lt;br /&gt;
|2023042510&lt;br /&gt;
|[https://moodledev.io/general/releases/4.1/4.1.4 Moodle LMS 4.1.4]&lt;br /&gt;
|[[Moodle Workplace 4.1 release notes#4.1.4|Moodle Workplace 4.1.4 rolling]]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 4.1.5&lt;br /&gt;
|22 August 2023&lt;br /&gt;
|2023042520&lt;br /&gt;
|[https://moodledev.io/general/releases/4.1/4.1.5 Moodle LMS 4.1.5]&lt;br /&gt;
|[[Moodle Workplace 4.1 release notes#4.1.5|Moodle Workplace 4.1.5 rolling]]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
 Support has ended&lt;br /&gt;
==Moodle Workplace 4.1==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
! Date&lt;br /&gt;
! Version number&lt;br /&gt;
! Moodle LMS release notes&lt;br /&gt;
! Moodle Workplace release notes&lt;br /&gt;
|-&lt;br /&gt;
! Moodle Workplace 4.1 (LTS)&lt;br /&gt;
| 11 January 2023&lt;br /&gt;
| 2023110100&lt;br /&gt;
| [https://moodledev.io/general/releases/4.1 Moodle LMS 4.1]&lt;br /&gt;
| [[Moodle Workplace 4.1 release notes|Moodle Workplace 4.1]]&lt;br /&gt;
|-&lt;br /&gt;
! Moodle Workplace 4.1.1&lt;br /&gt;
| 17 January 2023&lt;br /&gt;
| 2023011110&lt;br /&gt;
| [https://moodledev.io/general/releases/4.1/4.1.1 Moodle LMS 4.1.1]&lt;br /&gt;
| [[Moodle Workplace 4.1 release notes#4.1.1|Moodle Workplace 4.1.1]]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 4.1.2&lt;br /&gt;
|14 March 2023&lt;br /&gt;
|2023011120&lt;br /&gt;
|[https://moodledev.io/general/releases/4.1/4.1.2 Moodle LMS 4.1.2]&lt;br /&gt;
|[[Moodle Workplace 4.1 release notes#4.1.2|Moodle Workplace 4.1.2]]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 4.1.3&lt;br /&gt;
|25 April 2023&lt;br /&gt;
|2023011130&lt;br /&gt;
|[https://moodledev.io/general/releases/4.1/4.1.3 Moodle LMS 4.1.3]&lt;br /&gt;
|[[Moodle Workplace 4.1 release notes#4.1.3|Moodle Workplace 4.1.3]]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 4.1.4&lt;br /&gt;
|13 June 2023&lt;br /&gt;
|2023011140&lt;br /&gt;
|[https://moodledev.io/general/releases/4.1/4.1.4 Moodle LMS 4.1.4]&lt;br /&gt;
|[[Moodle Workplace 4.1 release notes#4.1.4|Moodle Workplace 4.1.4]]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 4.1.5&lt;br /&gt;
|22 August 2023&lt;br /&gt;
|2023011150&lt;br /&gt;
|[https://moodledev.io/general/releases/4.1/4.1.5 Moodle LMS 4.1.5]&lt;br /&gt;
|[[Moodle Workplace 4.1 release notes#4.1.5|Moodle Workplace 4.1.5]]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 4.1.6&lt;br /&gt;
|10 October 2023&lt;br /&gt;
|2023011160&lt;br /&gt;
|[https://moodledev.io/general/releases/4.1/4.1.6 Moodle LMS 4.1.6]&lt;br /&gt;
|[[Moodle Workplace 4.1 release notes#4.1.6|Moodle Workplace 4.1.6]]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 4.1.7&lt;br /&gt;
|12 December 2023&lt;br /&gt;
|2023011170&lt;br /&gt;
|[https://moodledev.io/general/releases/4.1/4.1.7 Moodle LMS 4.1.7]&lt;br /&gt;
|[[Moodle Workplace 4.1 release notes#4.1.7|Moodle Workplace 4.1.7]]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 4.1.8&lt;br /&gt;
|28 December 2023&lt;br /&gt;
|2023011180&lt;br /&gt;
|[https://moodledev.io/general/releases/4.1/4.1.8 Moodle LMS 4.1.8]&lt;br /&gt;
|[[Moodle Workplace 4.1 release notes#4.1.8|Moodle Workplace 4.1.8]]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
 Bug fixes in 4.1.x ended 12 December 2023.&lt;br /&gt;
 Bug fixes for security issues in 4.1.x will end 9 December 2025.&lt;br /&gt;
==Moodle Workplace 4.0==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
! Date&lt;br /&gt;
! Version number&lt;br /&gt;
! Moodle LMS release notes&lt;br /&gt;
! Moodle Workplace release notes&lt;br /&gt;
|-&lt;br /&gt;
! Moodle Workplace 4.0&lt;br /&gt;
| 14 October 2022&lt;br /&gt;
| 2022101400&lt;br /&gt;
| [https://moodledev.io/general/releases/4.0 Moodle LMS 4.0], [https://moodledev.io/general/releases/4.0/4.0.1 4.0.1], [https://moodledev.io/general/releases/4.0/4.0.2 4.0.2], [https://moodledev.io/general/releases/4.0/4.0.3 4.0.3], [https://moodledev.io/general/releases/4.0/4.0.4 4.0.4]&lt;br /&gt;
| [[Moodle Workplace 4.0 release notes|Moodle Workplace 4.0]]&lt;br /&gt;
|-&lt;br /&gt;
! Moodle Workplace 4.0.5&lt;br /&gt;
| 15 November 2022&lt;br /&gt;
| 2022111500&lt;br /&gt;
| [https://moodledev.io/general/releases/4.0/4.0.5 Moodle LMS 4.0.5]&lt;br /&gt;
| [[Moodle Workplace 4.0 release notes#4.0.5|Moodle Workplace 4.0.5]]&lt;br /&gt;
|-&lt;br /&gt;
! Moodle Workplace 4.0.6&lt;br /&gt;
| 17 January 2023&lt;br /&gt;
| 2022112810&lt;br /&gt;
| [https://moodledev.io/general/releases/4.0/4.0.6 Moodle LMS 4.0.6]&lt;br /&gt;
| [[Moodle Workplace 4.0 release notes#4.0.6|Moodle Workplace 4.0.6]]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 4.0.7&lt;br /&gt;
|14 March 2023&lt;br /&gt;
|2022112811&lt;br /&gt;
|[https://moodledev.io/general/releases/4.0/4.0.7 Moodle LMS 4.0.7]&lt;br /&gt;
|[[Moodle Workplace 4.0 release notes#4.0.7|Moodle Workplace 4.0.7]]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 4.0.8&lt;br /&gt;
|25 April 2023&lt;br /&gt;
|2022112812&lt;br /&gt;
|[https://moodledev.io/general/releases/4.0/4.0.8 Moodle LMS 4.0.8]&lt;br /&gt;
|[[Moodle Workplace 4.0 release notes#4.0.8|Moodle Workplace 4.0.8]]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 4.0.9&lt;br /&gt;
|13 June 2023&lt;br /&gt;
|2022112840&lt;br /&gt;
|[https://moodledev.io/general/releases/4.0/4.0.9 Moodle LMS 4.0.9]&lt;br /&gt;
|[[Moodle Workplace 4.0 release notes#4.0.9|Moodle Workplace 4.0.9]]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 4.0.10&lt;br /&gt;
|22 August 2023&lt;br /&gt;
|2022112850&lt;br /&gt;
|[https://moodledev.io/general/releases/4.0/4.0.10 Moodle LMS 4.0.10]&lt;br /&gt;
|[[Moodle Workplace 4.0 release notes#4.0.10|Moodle Workplace 4.0.10]]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 4.0.11&lt;br /&gt;
|10 October 2023&lt;br /&gt;
|2022112860&lt;br /&gt;
|[https://moodledev.io/general/releases/4.0/4.0.11 Moodle LMS 4.0.11]&lt;br /&gt;
|[[Moodle Workplace 4.0 release notes#4.0.11|Moodle Workplace 4.0.11]]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 4.0.12&lt;br /&gt;
|12 December 2023&lt;br /&gt;
|2022112870&lt;br /&gt;
|[https://moodledev.io/general/releases/4.0/4.0.12 Moodle LMS 4.0.12]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
 Support has ended&lt;br /&gt;
==Moodle Workplace 3.11==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
! Date&lt;br /&gt;
! Version number&lt;br /&gt;
! Moodle LMS release notes&lt;br /&gt;
! Moodle Workplace release notes&lt;br /&gt;
|-&lt;br /&gt;
! Moodle Workplace 3.11&lt;br /&gt;
| 8 June 2021&lt;br /&gt;
| 2021060800&lt;br /&gt;
| [[Moodle 3.11 release notes|Moodle LMS 3.11]]&lt;br /&gt;
| [[Moodle Workplace 3.11 release notes|Moodle Workplace 3.11]]&lt;br /&gt;
|-&lt;br /&gt;
! Moodle Workplace 3.11.1&lt;br /&gt;
| 20 July 2021&lt;br /&gt;
| 2021072000&lt;br /&gt;
| [[Moodle 3.11.1 release notes|Moodle LMS 3.11.1]]&lt;br /&gt;
| [[Moodle Workplace 3.11 release notes#3.11.1|Moodle Workplace 3.11.1]]&lt;br /&gt;
|-&lt;br /&gt;
! Moodle Workplace 3.11.2&lt;br /&gt;
| 30 July 2021&lt;br /&gt;
| 2021073000&lt;br /&gt;
| [[Moodle 3.11.2 release notes|Moodle LMS 3.11.2]]&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
! Moodle Workplace 3.11.3&lt;br /&gt;
| 20 September 2021&lt;br /&gt;
| 2021092000&lt;br /&gt;
| [[Moodle 3.11.3 release notes|Moodle LMS 3.11.3]]&lt;br /&gt;
| [[Moodle Workplace 3.11 release notes#3.11.3|Moodle Workplace 3.11.3]]&lt;br /&gt;
|-&lt;br /&gt;
! Moodle Workplace 3.11.4&lt;br /&gt;
| 25 November 2021&lt;br /&gt;
| 2021112500&lt;br /&gt;
| [[Moodle 3.11.4 release notes|Moodle LMS 3.11.4]]&lt;br /&gt;
| [[Moodle Workplace 3.11 release notes#3.11.4|Moodle Workplace 3.11.4]]&lt;br /&gt;
|-&lt;br /&gt;
! Moodle Workplace 3.11.5&lt;br /&gt;
| 18 January 2022&lt;br /&gt;
| 2022011800&lt;br /&gt;
| [[Moodle 3.11.5 release notes|Moodle LMS 3.11.5]]&lt;br /&gt;
| [[Moodle Workplace 3.11 release notes#3.11.5|Moodle Workplace 3.11.5]]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 3.11.6&lt;br /&gt;
|15 March 2022&lt;br /&gt;
|2022031500&lt;br /&gt;
|[[Moodle 3.11.6 release notes|Moodle LMS 3.11.6]]&lt;br /&gt;
|[[Moodle Workplace 3.11 release notes#3.11.6|Moodle Workplace 3.11.6]]&lt;br /&gt;
|-&lt;br /&gt;
! Moodle Workplace 3.11.7&lt;br /&gt;
| 10 May 2022&lt;br /&gt;
| 2022031610&lt;br /&gt;
| [[Moodle 3.11.7 release notes|Moodle LMS 3.11.7]]&lt;br /&gt;
| [[Moodle Workplace 3.11 release notes#3.11.7|Moodle Workplace 3.11.7]]&lt;br /&gt;
|-&lt;br /&gt;
! Moodle Workplace 3.11.8&lt;br /&gt;
| 12 July 2022&lt;br /&gt;
| 2022031620&lt;br /&gt;
| [[Moodle 3.11.8 release notes|Moodle LMS 3.11.8]]&lt;br /&gt;
| [[Moodle Workplace 3.11 release notes#3.11.8|Moodle Workplace 3.11.8]]&lt;br /&gt;
|-&lt;br /&gt;
! Moodle Workplace 3.11.9&lt;br /&gt;
| 23 August 2022&lt;br /&gt;
| 2022031630&lt;br /&gt;
| [https://moodledev.io/general/releases/3.11/3.11.9 Moodle LMS 3.11.9]&lt;br /&gt;
| [[Moodle Workplace 3.11 release notes#3.11.9|Moodle Workplace 3.11.9]]&lt;br /&gt;
|-&lt;br /&gt;
! Moodle Workplace 3.11.10&lt;br /&gt;
| 13 September 2022&lt;br /&gt;
| 2022031640&lt;br /&gt;
| [https://moodledev.io/general/releases/3.11/3.11.10 Moodle LMS 3.11.10]&lt;br /&gt;
| [[Moodle Workplace 3.11 release notes#3.11.10|Moodle Workplace 3.11.10]]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 3.11.11&lt;br /&gt;
|15 November 2022&lt;br /&gt;
|2022031650&lt;br /&gt;
|[https://moodledev.io/general/releases/3.11/3.11.11 Moodle LMS 3.11.11]&lt;br /&gt;
|[[Moodle Workplace 3.11 release notes#3.11.11|Moodle Workplace 3.11.11]]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 3.11.12&lt;br /&gt;
|17 January 2023&lt;br /&gt;
|2022031660&lt;br /&gt;
|[https://moodledev.io/general/releases/3.11/3.11.12 Moodle LMS 3.11.12]&lt;br /&gt;
|[[Moodle Workplace 3.11 release notes#3.11.12|Moodle Workplace 3.11.12]]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 3.11.13&lt;br /&gt;
|14 March 2023&lt;br /&gt;
|2022031670&lt;br /&gt;
|[https://moodledev.io/general/releases/3.11/3.11.13 Moodle LMS 3.11.13]&lt;br /&gt;
|[[Moodle Workplace 3.11 release notes#3.11.13|Moodle Workplace 3.11.13]]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 3.11.14&lt;br /&gt;
|25 April 2023&lt;br /&gt;
|2022031680&lt;br /&gt;
|[https://moodledev.io/general/releases/3.11/3.11.14 Moodle LMS 3.11.14]&lt;br /&gt;
|[[Moodle Workplace 3.11 release notes#3.11.14|Moodle Workplace 3.11.14]]&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 3.11.15&lt;br /&gt;
|13 June 2023&lt;br /&gt;
|2022031690&lt;br /&gt;
|[https://moodledev.io/general/releases/3.11/3.11.15 Moodle LMS 3.11.15]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 3.11.16&lt;br /&gt;
|22 August 2023&lt;br /&gt;
|2022031700&lt;br /&gt;
|[https://moodledev.io/general/releases/3.11/3.11.16 Moodle LMS 3.11.16]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 3.11.17&lt;br /&gt;
|10 October 2023&lt;br /&gt;
|2022031710&lt;br /&gt;
|[https://moodledev.io/general/releases/3.11/3.11.17 Moodle LMS 3.11.17]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 3.11.18&lt;br /&gt;
|12 December 2023&lt;br /&gt;
|2022031720&lt;br /&gt;
|[https://moodledev.io/general/releases/3.11/3.11.18 Moodle LMS 3.11.18]&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
 Support has ended&lt;br /&gt;
==Moodle Workplace 3.10==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
! Date&lt;br /&gt;
! Version number&lt;br /&gt;
! Moodle LMS release notes&lt;br /&gt;
! Moodle Workplace release notes&lt;br /&gt;
|-&lt;br /&gt;
! Moodle Workplace 3.10&lt;br /&gt;
| 1 December 2020&lt;br /&gt;
| 2020120100&lt;br /&gt;
| [[Moodle 3.10 release notes|Moodle LMS 3.10]]&lt;br /&gt;
| [[Moodle Workplace 3.10 release notes#3.10|Moodle Workplace 3.10]]&lt;br /&gt;
|-&lt;br /&gt;
! Moodle Workplace 3.10.1&lt;br /&gt;
| 19 January 2021&lt;br /&gt;
| 2021011900&lt;br /&gt;
| [[Moodle 3.10.1 release notes|Moodle LMS 3.10.1]]&lt;br /&gt;
| [[Moodle Workplace 3.10 release notes#3.10.1|Moodle Workplace 3.10.1]]&lt;br /&gt;
|-&lt;br /&gt;
! Moodle Workplace 3.10.2&lt;br /&gt;
| 9 March 2021&lt;br /&gt;
| 2021030800&lt;br /&gt;
| [[Moodle 3.10.2 release notes|Moodle LMS 3.10.2]]&lt;br /&gt;
| [[Moodle Workplace 3.10 release notes#3.10.2|Moodle Workplace 3.10.2]]&lt;br /&gt;
|-&lt;br /&gt;
! Moodle Workplace 3.10.3&lt;br /&gt;
| 25 March 2021&lt;br /&gt;
| 2021032500&lt;br /&gt;
| [[Moodle 3.10.3 release notes|Moodle LMS 3.10.3]]&lt;br /&gt;
| [[Moodle Workplace 3.10 release notes#3.10.3|Moodle Workplace 3.10.3]]&lt;br /&gt;
|-&lt;br /&gt;
! Moodle Workplace 3.10.4&lt;br /&gt;
| 10 May 2021&lt;br /&gt;
| 2021051000&lt;br /&gt;
| [[Moodle 3.10.4 release notes|Moodle LMS 3.10.4]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 3.10.5&lt;br /&gt;
|13 July 2021&lt;br /&gt;
|2021051200&lt;br /&gt;
|[[Moodle 3.10.5 release notes|Moodle LMS 3.10.5]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 3.10.6&lt;br /&gt;
|30 July 2021&lt;br /&gt;
|2021051210&lt;br /&gt;
|[[Moodle 3.10.6 release notes|Moodle LMS 3.10.6]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 3.10.7&lt;br /&gt;
|16 September 2021&lt;br /&gt;
|2021051220&lt;br /&gt;
|[[Moodle 3.10.7 release notes|Moodle LMS 3.10.7]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 3.10.8&lt;br /&gt;
|17 November 2021&lt;br /&gt;
|2021051230&lt;br /&gt;
|[[Moodle 3.10.8 release notes|Moodle LMS 3.10.8]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 3.10.9&lt;br /&gt;
|18 January 2021&lt;br /&gt;
|2021051240&lt;br /&gt;
|[[Moodle 3.10.9 release notes|Moodle LMS 3.10.9]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 3.10.10&lt;br /&gt;
|15 March 2022&lt;br /&gt;
|2021051250&lt;br /&gt;
|[[Moodle 3.10.10 release notes|Moodle LMS 3.10.10]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
!Moodle Workplace 3.10.11&lt;br /&gt;
|10 May 2022&lt;br /&gt;
|2021051260&lt;br /&gt;
|[[Moodle 3.10.11 release notes|Moodle LMS 3.10.11]]&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
 Support has ended&lt;br /&gt;
==Moodle Workplace 3.9==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
! Date&lt;br /&gt;
! Version number&lt;br /&gt;
! Moodle LMS release notes&lt;br /&gt;
! Moodle Workplace release notes&lt;br /&gt;
|-&lt;br /&gt;
! Moodle Workplace 3.9&lt;br /&gt;
| 30 June 2020&lt;br /&gt;
| 2020063000&lt;br /&gt;
| [[Moodle 3.9 release notes|Moodle LMS 3.9]]&lt;br /&gt;
| [[Moodle Workplace 3.9 release notes#3.9|Moodle Workplace 3.9]]&lt;br /&gt;
|-&lt;br /&gt;
! Moodle Workplace 3.9.1&lt;br /&gt;
| 15 July 2020&lt;br /&gt;
| 2020071500&lt;br /&gt;
| [[Moodle 3.9.1 release notes|Moodle LMS 3.9.1]]&lt;br /&gt;
| [[Moodle Workplace 3.9 release notes#3.9.1|Moodle Workplace 3.9.1]]&lt;br /&gt;
|-&lt;br /&gt;
! Moodle Workplace 3.9.2&lt;br /&gt;
| 24 September 2020&lt;br /&gt;
| 2020092400&lt;br /&gt;
| [[Moodle 3.9.2 release notes|Moodle LMS 3.9.2]]&lt;br /&gt;
| [[Moodle Workplace 3.9 release notes#3.9.2|Moodle Workplace 3.9.2]]&lt;br /&gt;
|-&lt;br /&gt;
! Moodle Workplace 3.9.3&lt;br /&gt;
| 10 November 2020&lt;br /&gt;
| 2020111000&lt;br /&gt;
| [[Moodle 3.9.3 release notes|Moodle LMS 3.9.3]]&lt;br /&gt;
| &lt;br /&gt;
|}&lt;br /&gt;
 Support has ended&lt;br /&gt;
==Moodle Workplace 3.8==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
! Date&lt;br /&gt;
! Version number&lt;br /&gt;
! Moodle LMS release notes&lt;br /&gt;
! Moodle Workplace release notes&lt;br /&gt;
|-&lt;br /&gt;
! Moodle Workplace 3.8&lt;br /&gt;
| 26 November 2019&lt;br /&gt;
| 2019112600&lt;br /&gt;
| [[Moodle 3.8 release notes|Moodle LMS 3.8]]&lt;br /&gt;
| [[Moodle Workplace 3.8 release notes#3.8|Moodle Workplace 3.8]]&lt;br /&gt;
|-&lt;br /&gt;
! Moodle Workplace 3.8.1&lt;br /&gt;
| 20 January 2020&lt;br /&gt;
| 2020012000&lt;br /&gt;
| [[Moodle 3.8.1 release notes|Moodle LMS 3.8.1]]&lt;br /&gt;
| [[Moodle Workplace 3.8 release notes#3.8.1|Moodle Workplace 3.8.1]]&lt;br /&gt;
|-&lt;br /&gt;
! Moodle Workplace 3.8.2&lt;br /&gt;
| 10 March 2020&lt;br /&gt;
| 2020031000&lt;br /&gt;
| [[Moodle 3.8.2 release notes|Moodle LMS 3.8.2]]&lt;br /&gt;
| [[Moodle Workplace 3.8 release notes#3.8.2|Moodle Workplace 3.8.2]]&lt;br /&gt;
|-&lt;br /&gt;
! Moodle Workplace 3.8.3&lt;br /&gt;
| 12 May 2020&lt;br /&gt;
| 2020051200&lt;br /&gt;
| [[Moodle 3.8.3 release notes|Moodle LMS 3.8.3]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle Workplace 3.8.4&lt;br /&gt;
| 9 June 2020&lt;br /&gt;
| 2020060900&lt;br /&gt;
| [[Moodle 3.8.4 release notes|Moodle LMS 3.8.4]]&lt;br /&gt;
| &lt;br /&gt;
|}&lt;br /&gt;
 Support has ended&lt;br /&gt;
==Moodle Workplace 3.7==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
! Date&lt;br /&gt;
! Version number&lt;br /&gt;
! Moodle LMS release notes&lt;br /&gt;
! Moodle Workplace release notes&lt;br /&gt;
|-&lt;br /&gt;
! Moodle Workplace 3.7 (PR)&lt;br /&gt;
| 25 June 2019&lt;br /&gt;
| 2019062500&lt;br /&gt;
| [[Moodle 3.7 release notes|Moodle LMS 3.7]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle Workplace 3.7.2&lt;br /&gt;
| 10 September 2019&lt;br /&gt;
| 2019091000&lt;br /&gt;
| [[Moodle 3.7.2 release notes|Moodle LMS 3.7.2]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
! Moodle Workplace 3.7.3&lt;br /&gt;
| 12 November 2019&lt;br /&gt;
| 2019111200&lt;br /&gt;
| [[Moodle 3.7.3 release notes|Moodle LMS 3.7.3]]&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
 Support has ended&lt;br /&gt;
&lt;br /&gt;
[[Category: Workplace]]&lt;br /&gt;
[[Category:Release notes]]&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Web_services_files_handling&amp;diff=58268</id>
		<title>Web services files handling</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Web_services_files_handling&amp;diff=58268"/>
		<updated>2021-01-31T15:15:50Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: /* CURL example */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
&lt;br /&gt;
Since Moodle 2.0, we provide web service functions to upload and download files. They are:&lt;br /&gt;
&lt;br /&gt;
# moodle_file_get_files (Deprecated, use core_files_get_files since moodle 2.2 onward)&lt;br /&gt;
# moodle_file_upload (Deprecated, use core_files_upload since moodle 2.2 onward)&lt;br /&gt;
&lt;br /&gt;
File contents are encoded in base64, and for web service transmission, it&#039;s not efficient. Mobile devices don&#039;t have enough memory to decode/encode web service request/response containing large files.&lt;br /&gt;
&lt;br /&gt;
So we developed some alternative solutions to upload/download files.&lt;br /&gt;
&lt;br /&gt;
== File upload ==&lt;br /&gt;
&lt;br /&gt;
The entry point is &#039;&#039;/webservice/upload.php&#039;&#039;, simply use HTTP POST method to upload files, it requires a web service token for authentication. If the upload is successfully, the files will be saved, prior to at least Moodle 2.9 in the user private file area but since in the user draft area.  Previously you could force the files to be saved in the draft area by specifying the then  optional parameter: &#039;&#039;filearea=draft&#039;&#039;.  Since at least Moodle 2.9, only two optional parameters are used, &#039;&#039;itemid&#039;&#039; to specify the draft area id – default 0 which is a new draft area - and &#039;&#039;filepath&#039;&#039; default  \‘/\’ to specify the file’s path.&lt;br /&gt;
&lt;br /&gt;
It is envisaged the &#039;&#039;itemid&#039;&#039; parameter will be used when the files are uploaded singularly in separate HTTP calls and the files are required to be in the same draft file area.  The client retrieves the &#039;&#039;itemid&#039;&#039; of the first uploaded file and uses it in subsequent uploads to specify the files must be saved in the same draft file area.&lt;br /&gt;
&lt;br /&gt;
On every successful upload, the file/s information are returned in JSON format. If an error occurs, an error message will be sent back in JSON format too.&lt;br /&gt;
&lt;br /&gt;
Say, we want to upload &amp;lt;tt&amp;gt;users.csv&amp;lt;/tt&amp;gt; from current directory using &amp;lt;tt&amp;gt;curl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$ curl -X POST -F &amp;quot;file_1=@users.csv&amp;quot; https://SITENAME/webservice/upload.php?token=TOKEN \&lt;br /&gt;
| jq&lt;br /&gt;
&lt;br /&gt;
[&lt;br /&gt;
  {&lt;br /&gt;
    &amp;quot;component&amp;quot;: &amp;quot;user&amp;quot;,&lt;br /&gt;
    &amp;quot;contextid&amp;quot;: 567,&lt;br /&gt;
    &amp;quot;userid&amp;quot;: &amp;quot;123&amp;quot;,&lt;br /&gt;
    &amp;quot;filearea&amp;quot;: &amp;quot;draft&amp;quot;,&lt;br /&gt;
    &amp;quot;filename&amp;quot;: &amp;quot;users.csv&amp;quot;,&lt;br /&gt;
    &amp;quot;filepath&amp;quot;: &amp;quot;/&amp;quot;,&lt;br /&gt;
    &amp;quot;itemid&amp;quot;: 880413555,&lt;br /&gt;
    &amp;quot;license&amp;quot;: &amp;quot;allrightsreserved&amp;quot;,&lt;br /&gt;
    &amp;quot;author&amp;quot;: &amp;quot;User User&amp;quot;,&lt;br /&gt;
    &amp;quot;source&amp;quot;: &amp;quot;O:8:\&amp;quot;stdClass\&amp;quot;:1:{s:6:\&amp;quot;source\&amp;quot;;s:13:\&amp;quot;users.csv\&amp;quot;;}&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once all the files are uploaded, you can call the webservice that accepts files and pass it the &#039;&#039;itemid&#039;&#039; of the draft area containing the list of files for the request. The service can identify the uploads and manipulate them as necessary.  An example of a webservice that accepts files is: &#039;&#039;mod_assign_save_submission&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
To accept file uploads, the the service must allow &amp;quot;files download&amp;quot; (&#039;&#039;Administration &amp;gt; Plugins &amp;gt; Web services &amp;gt; Manage services &amp;gt; Edit service &amp;gt; Advanced button&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
There is an oldish code example on [https://github.com/moodlehq/sample-ws-clients/tree/master/PHP-HTTP-filehandling code example on Github].&lt;br /&gt;
&lt;br /&gt;
== File download ==&lt;br /&gt;
We serve the files through &#039;&#039;/webservice/pluginfile.php&#039;&#039;. This script requires a web service token for authentication. &lt;br /&gt;
&lt;br /&gt;
Look at the [https://github.com/moodlehq/sample-ws-clients/tree/master/PHP-HTTP-filehandling code example on Github].&lt;br /&gt;
&lt;br /&gt;
In case of issue, think to check that:&lt;br /&gt;
# the service associated with the token allow &amp;quot;&#039;&#039;files download&#039;&#039;&amp;quot;  (&#039;&#039;Administration &amp;gt; Plugins &amp;gt; Web services &amp;gt; Manage services &amp;gt; Edit service &amp;gt; Advanced button&#039;&#039;)&lt;br /&gt;
# the web service is valid&lt;br /&gt;
&lt;br /&gt;
Note: you could notice that &#039;&#039;/webservice/pluginfile.php&#039;&#039; has the exact same stucture than &#039;&#039;/pluginfile.php&#039;&#039;. We don&#039;t serve the files through &#039;&#039;/pluginfile.php&#039;&#039; for web service clients because this script requires user&#039;s login session to work. It&#039;s why it might not be an option for web service client.&lt;br /&gt;
&lt;br /&gt;
== Returning files in Web Services ==&lt;br /&gt;
&lt;br /&gt;
Since Moodle 3.2, you can return a complete file area list via Web Services using the static get_area_files method in external_util.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    $forum-&amp;gt;introfiles = external_util::get_area_files($context-&amp;gt;id, &#039;mod_forum&#039;, &#039;intro&#039;, false, false);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also use the external_files structure definition in combination with the method to return the most common file fields required by WS clientes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
     public static function get_forums_by_courses_returns() {&lt;br /&gt;
        return new external_multiple_structure(&lt;br /&gt;
            new external_single_structure(&lt;br /&gt;
                array(&lt;br /&gt;
                    &#039;id&#039; =&amp;gt; new external_value(PARAM_INT, &#039;Forum id&#039;),&lt;br /&gt;
                     ....&lt;br /&gt;
                    &#039;introfiles&#039; =&amp;gt; new external_files(&#039;Files in the introduction text&#039;, VALUE_OPTIONAL),&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [[Web_services|Web services developer documentation]]&lt;br /&gt;
* [[:en:Web_services|Web services user documentation]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Web_Services]]&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Web_services_files_handling&amp;diff=58267</id>
		<title>Web services files handling</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Web_services_files_handling&amp;diff=58267"/>
		<updated>2021-01-31T15:15:36Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: /* File upload */ add example how to upload using curl&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
&lt;br /&gt;
Since Moodle 2.0, we provide web service functions to upload and download files. They are:&lt;br /&gt;
&lt;br /&gt;
# moodle_file_get_files (Deprecated, use core_files_get_files since moodle 2.2 onward)&lt;br /&gt;
# moodle_file_upload (Deprecated, use core_files_upload since moodle 2.2 onward)&lt;br /&gt;
&lt;br /&gt;
File contents are encoded in base64, and for web service transmission, it&#039;s not efficient. Mobile devices don&#039;t have enough memory to decode/encode web service request/response containing large files.&lt;br /&gt;
&lt;br /&gt;
So we developed some alternative solutions to upload/download files.&lt;br /&gt;
&lt;br /&gt;
== File upload ==&lt;br /&gt;
&lt;br /&gt;
The entry point is &#039;&#039;/webservice/upload.php&#039;&#039;, simply use HTTP POST method to upload files, it requires a web service token for authentication. If the upload is successfully, the files will be saved, prior to at least Moodle 2.9 in the user private file area but since in the user draft area.  Previously you could force the files to be saved in the draft area by specifying the then  optional parameter: &#039;&#039;filearea=draft&#039;&#039;.  Since at least Moodle 2.9, only two optional parameters are used, &#039;&#039;itemid&#039;&#039; to specify the draft area id – default 0 which is a new draft area - and &#039;&#039;filepath&#039;&#039; default  \‘/\’ to specify the file’s path.&lt;br /&gt;
&lt;br /&gt;
It is envisaged the &#039;&#039;itemid&#039;&#039; parameter will be used when the files are uploaded singularly in separate HTTP calls and the files are required to be in the same draft file area.  The client retrieves the &#039;&#039;itemid&#039;&#039; of the first uploaded file and uses it in subsequent uploads to specify the files must be saved in the same draft file area.&lt;br /&gt;
&lt;br /&gt;
On every successful upload, the file/s information are returned in JSON format. If an error occurs, an error message will be sent back in JSON format too.&lt;br /&gt;
&lt;br /&gt;
Say, we want to upload &amp;lt;tt&amp;gt;users.csv&amp;lt;/tt&amp;gt; from current directory using &amp;lt;tt&amp;gt;curl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;code bash&amp;gt;&lt;br /&gt;
$ curl -X POST -F &amp;quot;file_1=@users.csv&amp;quot; https://SITENAME/webservice/upload.php?token=TOKEN \&lt;br /&gt;
| jq&lt;br /&gt;
&lt;br /&gt;
[&lt;br /&gt;
  {&lt;br /&gt;
    &amp;quot;component&amp;quot;: &amp;quot;user&amp;quot;,&lt;br /&gt;
    &amp;quot;contextid&amp;quot;: 567,&lt;br /&gt;
    &amp;quot;userid&amp;quot;: &amp;quot;123&amp;quot;,&lt;br /&gt;
    &amp;quot;filearea&amp;quot;: &amp;quot;draft&amp;quot;,&lt;br /&gt;
    &amp;quot;filename&amp;quot;: &amp;quot;users.csv&amp;quot;,&lt;br /&gt;
    &amp;quot;filepath&amp;quot;: &amp;quot;/&amp;quot;,&lt;br /&gt;
    &amp;quot;itemid&amp;quot;: 880413555,&lt;br /&gt;
    &amp;quot;license&amp;quot;: &amp;quot;allrightsreserved&amp;quot;,&lt;br /&gt;
    &amp;quot;author&amp;quot;: &amp;quot;User User&amp;quot;,&lt;br /&gt;
    &amp;quot;source&amp;quot;: &amp;quot;O:8:\&amp;quot;stdClass\&amp;quot;:1:{s:6:\&amp;quot;source\&amp;quot;;s:13:\&amp;quot;users.csv\&amp;quot;;}&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once all the files are uploaded, you can call the webservice that accepts files and pass it the &#039;&#039;itemid&#039;&#039; of the draft area containing the list of files for the request. The service can identify the uploads and manipulate them as necessary.  An example of a webservice that accepts files is: &#039;&#039;mod_assign_save_submission&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
To accept file uploads, the the service must allow &amp;quot;files download&amp;quot; (&#039;&#039;Administration &amp;gt; Plugins &amp;gt; Web services &amp;gt; Manage services &amp;gt; Edit service &amp;gt; Advanced button&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
There is an oldish code example on [https://github.com/moodlehq/sample-ws-clients/tree/master/PHP-HTTP-filehandling code example on Github].&lt;br /&gt;
&lt;br /&gt;
=== CURL example ===&lt;br /&gt;
&lt;br /&gt;
Say your file&lt;br /&gt;
&lt;br /&gt;
== File download ==&lt;br /&gt;
We serve the files through &#039;&#039;/webservice/pluginfile.php&#039;&#039;. This script requires a web service token for authentication. &lt;br /&gt;
&lt;br /&gt;
Look at the [https://github.com/moodlehq/sample-ws-clients/tree/master/PHP-HTTP-filehandling code example on Github].&lt;br /&gt;
&lt;br /&gt;
In case of issue, think to check that:&lt;br /&gt;
# the service associated with the token allow &amp;quot;&#039;&#039;files download&#039;&#039;&amp;quot;  (&#039;&#039;Administration &amp;gt; Plugins &amp;gt; Web services &amp;gt; Manage services &amp;gt; Edit service &amp;gt; Advanced button&#039;&#039;)&lt;br /&gt;
# the web service is valid&lt;br /&gt;
&lt;br /&gt;
Note: you could notice that &#039;&#039;/webservice/pluginfile.php&#039;&#039; has the exact same stucture than &#039;&#039;/pluginfile.php&#039;&#039;. We don&#039;t serve the files through &#039;&#039;/pluginfile.php&#039;&#039; for web service clients because this script requires user&#039;s login session to work. It&#039;s why it might not be an option for web service client.&lt;br /&gt;
&lt;br /&gt;
== Returning files in Web Services ==&lt;br /&gt;
&lt;br /&gt;
Since Moodle 3.2, you can return a complete file area list via Web Services using the static get_area_files method in external_util.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    $forum-&amp;gt;introfiles = external_util::get_area_files($context-&amp;gt;id, &#039;mod_forum&#039;, &#039;intro&#039;, false, false);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also use the external_files structure definition in combination with the method to return the most common file fields required by WS clientes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
     public static function get_forums_by_courses_returns() {&lt;br /&gt;
        return new external_multiple_structure(&lt;br /&gt;
            new external_single_structure(&lt;br /&gt;
                array(&lt;br /&gt;
                    &#039;id&#039; =&amp;gt; new external_value(PARAM_INT, &#039;Forum id&#039;),&lt;br /&gt;
                     ....&lt;br /&gt;
                    &#039;introfiles&#039; =&amp;gt; new external_files(&#039;Files in the introduction text&#039;, VALUE_OPTIONAL),&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [[Web_services|Web services developer documentation]]&lt;br /&gt;
* [[:en:Web_services|Web services user documentation]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Web_Services]]&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Writing_acceptance_tests&amp;diff=56592</id>
		<title>Writing acceptance tests</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Writing_acceptance_tests&amp;diff=56592"/>
		<updated>2019-10-31T14:55:00Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: Added icon selector to the list&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
This documentation gives some hints, how to write behat tests for core and for plugins. The focus of the documentation is on behat tests for plugins. They are written in some kind of natural language and describe how the front-end of moodle should behave, when a user interacts with it.&lt;br /&gt;
&lt;br /&gt;
Each test consists of a set of so called steps in a GIVEN, WHEN, THEN style:&lt;br /&gt;
* &#039;&#039;&#039;GIVEN&#039;&#039;&#039;: These steps outline the state of your moodle platform at the start of your test. Here you can create users, courses and plugin instances.&lt;br /&gt;
* &#039;&#039;&#039;WHEN&#039;&#039;&#039;: These steps usually execute the functionality of your plugin, which is under test.&lt;br /&gt;
* &#039;&#039;&#039;THEN&#039;&#039;&#039;: These steps describe the expected behaviour of your plugin. They usually check if different elements can or can&#039;t be seen.&lt;br /&gt;
This matches the standard [http://xunitpatterns.com/Four%20Phase%20Test.html Four-phase test pattern]. The fourth phase is &#039;tear-down&#039; which we don&#039;t need because Behat automatically cleans up after each test.&lt;br /&gt;
&lt;br /&gt;
To initialize and run your tests, please follow the instructions of [[Running_acceptance_test]].&lt;br /&gt;
&lt;br /&gt;
== Create your own tests ==&lt;br /&gt;
Behat tests are located within the directory tests/behat of your plugin.&lt;br /&gt;
The different tests are defined in files with the ending *.feature.&lt;br /&gt;
First, you have to define the header of your test:&lt;br /&gt;
&amp;lt;code behat&amp;gt;&lt;br /&gt;
@mod @mod_yourplugin @javascript&lt;br /&gt;
Feature: Here comes a description of your user story.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The tags on top of the feature description can be used to select specific test cases when running the tests.&lt;br /&gt;
The &#039;@javascript&#039; tag should only be used, if javascript is needed to execute your test. This is dependent on the step you will use in your definition.&lt;br /&gt;
Javascript tests are usually much slower than tests executed without javascript.&lt;br /&gt;
&lt;br /&gt;
Afterwards you can specify a scenario:&lt;br /&gt;
&amp;lt;code behat&amp;gt;&lt;br /&gt;
@javascript&lt;br /&gt;
  Scenario: Description of your scenario, which you want to test.&lt;br /&gt;
    When I log in as &amp;quot;student1&amp;quot;&lt;br /&gt;
    And I am on &amp;quot;Course 1&amp;quot; course homepage&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Again you can define specific tags. Afterwards you write the steps, which should be executed during your test.&lt;br /&gt;
&lt;br /&gt;
==== Multiple Scenarios ====&lt;br /&gt;
You can have an arbitrary amount of scenarios within a test. Please make sure they all belong to the same feature.&lt;br /&gt;
If you have certain steps, which should be executed for every scenario of a feature, you can define them using a background:&lt;br /&gt;
&amp;lt;code behat&amp;gt;&lt;br /&gt;
Background:&lt;br /&gt;
    Given the following &amp;quot;courses&amp;quot; exist:&lt;br /&gt;
      | fullname | shortname | category | groupmode |&lt;br /&gt;
      | Course 1 | C1        | 0        | 1         |&lt;br /&gt;
    And the following &amp;quot;users&amp;quot; exist:&lt;br /&gt;
      | username | firstname | lastname | email |&lt;br /&gt;
      | teacher1 | Theo | Teacher | teacher1@example.com |&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This is usually used, to define the different &#039;&#039;&#039;GIVEN&#039;&#039;&#039; steps.&lt;br /&gt;
&lt;br /&gt;
==== Use existing steps ====&lt;br /&gt;
There are different ways how to effectively browse the available existing steps:&lt;br /&gt;
&lt;br /&gt;
====== Moodle Administration ======&lt;br /&gt;
Moodle offers within its administration menu under Site Administration &amp;gt; Development &amp;gt; Acceptance Testing a complete and searchable list of all available step definitions.&lt;br /&gt;
However, make sure you installed the behat test site first!&lt;br /&gt;
&lt;br /&gt;
====== PhpStorm ======&lt;br /&gt;
In PhpStorm or IntelliJ you can install the behat extension. Then you get auto completions within feature files, which helps a lot during behat test development.&lt;br /&gt;
&lt;br /&gt;
==== Providing values to steps ====&lt;br /&gt;
Most of the steps requires values, there are methods to provide values to steps, the method depends on the step specification.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;A string/text&#039;&#039;&#039;; is the most common case, the texts are wrapped between double quotes (&amp;quot; character) you have to replace the info about the expected value for your value; for example something like &#039;&#039;&#039;I press &amp;quot;BUTTON_STRING&amp;quot;&#039;&#039;&#039; should become &#039;&#039;&#039;I press &amp;quot;Save and return to course&amp;quot;&#039;&#039;&#039;. If you want to add a string which contains a &amp;quot; character, you can escape it with \&amp;quot;, for example &#039;&#039;&#039;I fill the &amp;quot;Name&amp;quot; field with &amp;quot;Alan alias \&amp;quot;the legend\&amp;quot;&amp;quot;&#039;&#039;&#039;. You can identify this steps because they ends with &#039;&#039;&#039;_STRING&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;A number&#039;&#039;&#039;; some steps requires numbers as values, to be more specific an undetermined number of digits from 0 to 9 (Natural numbers + 0) you can identify them because the expected value info string ends with &#039;&#039;&#039;_NUMBER&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;A table&#039;&#039;&#039;; is a relation between values, the most common use of it is to fill forms. The steps which requires tables are easily identifiable because they finish with &#039;&#039;&#039;:&#039;&#039;&#039; The steps description gives info about what the table columns must contain, for example &#039;&#039;&#039;Fills a moodle form with field/value data&#039;&#039;&#039;. Here you don&#039;t need to escape the double quotes if you want to include them as part of the value.&lt;br /&gt;
* &#039;&#039;&#039;A PyString&#039;&#039;&#039;; is a multiline string, most commonly used to fill out forms when a newline is required. Like steps with tables, steps which require PyStrings will end with &amp;quot;:&amp;quot;&lt;br /&gt;
* &#039;&#039;&#039;A field value&#039;&#039;&#039;; There are many different field types, if an argument requires a field value the expected value will depend on the field type:&lt;br /&gt;
** Text-based fields: It expects the text. This includes textareas, input type text, input type password...&lt;br /&gt;
** Checkbox: It expects 1 to check and for checked and &amp;quot;&amp;quot; to uncheck or for unchecked&lt;br /&gt;
** Select: It expects the option text or the option value. In case you interact with a multi-select you should specify the options separating them with commas. For example: &#039;&#039;&#039;option1, option2, option3&#039;&#039;&#039;&lt;br /&gt;
** Radio: The text of the radio option&lt;br /&gt;
* &#039;&#039;&#039;A selector&#039;&#039;&#039;; there are steps that can be used with different kinds of elements, for example &#039;&#039;&#039;I click on &amp;quot;User Name&amp;quot; &amp;quot;link&amp;quot;&#039;&#039;&#039; or &#039;&#039;&#039;I click on &amp;quot;User Name&amp;quot; &amp;quot;button&amp;quot;&#039;&#039;&#039; this is a closed list of elements, they always works together with another argument, where you specify the locator (eg. the link text in a link) In the &#039;Acceptance testing&#039; interface you can see a drop-down menu to select one of these options:&lt;br /&gt;
** field - for searching a field by its id, name, value or label&lt;br /&gt;
** link - for searching a link by its href, id, title, img alt or value&lt;br /&gt;
** button - for searching a button by its name, id, value, img alt or title&lt;br /&gt;
** link_or_button - for searching for both, links and buttons&lt;br /&gt;
** select - for searching a select field by its id, name or label&lt;br /&gt;
** checkbox - for searching a checkbox by its id, name, or label&lt;br /&gt;
** radio - for searching a radio button by its id, name, or label&lt;br /&gt;
** file - for searching a file input by its id, name, or label&lt;br /&gt;
** optgroup - for searching optgroup by its label&lt;br /&gt;
** option - for searching an option by its content&lt;br /&gt;
** dialogue - for searching a dialogue with the specified header text&lt;br /&gt;
** filemanager - for searching a filemanager by it&#039;s id or label&lt;br /&gt;
** block - for searching a Moodle block by it&#039;s English name or it&#039;s frankenstyle name&lt;br /&gt;
** section - for searching for a section on a course page by it&#039;s title or its written out date (e.g. &amp;quot;1 January - 7 January&amp;quot;). Use &amp;quot;frontpage&amp;quot; &amp;quot;section&amp;quot; for the frontpage section if it has no title (default)&lt;br /&gt;
** activity - for searching for an activity module in a course list by it&#039;s title&lt;br /&gt;
** region - for searching a Moodle page region with that id, in fact it works with all the page&#039;s ids&lt;br /&gt;
** table_row - for searching a table row which contains the specified text&lt;br /&gt;
** table - for searching a table by its id or caption&lt;br /&gt;
** icon - for searching an icon by its title &lt;br /&gt;
** fieldset - for searching a fieldset by it&#039;s id or legend&lt;br /&gt;
** css_element - for searching an element by its CSS selector&lt;br /&gt;
** xpath_element - for searching an element by its XPath&lt;br /&gt;
* &#039;&#039;&#039;A text selector&#039;&#039;&#039;; similar to a selector but those are the elements that returns an area of the DOM, they are useful in steps following the format &#039;&#039;&#039;... in the &amp;quot;Community finder&amp;quot; &amp;quot;block&amp;quot;&#039;&#039;&#039; where you are clicking or looking for some text inside a specific area. In the &#039;Acceptance testing&#039; interface you can see a drop-down menu to select one of these options:&lt;br /&gt;
** dialogue - for searching a dialogue with the specified header text&lt;br /&gt;
** block - for searching a Moodle block by it&#039;s English name or it&#039;s frankenstyle name&lt;br /&gt;
** section - for searching for a section on a course page by it&#039;s title or its written out date (e.g. &amp;quot;1 January - 7 January&amp;quot;). Use &amp;quot;frontpage&amp;quot; &amp;quot;section&amp;quot; for the frontpage section if it has no title (default)&lt;br /&gt;
** activity - for searching for an activity module in a course list by it&#039;s title&lt;br /&gt;
** region - for searching a Moodle page region with that id, in fact it works with all the page&#039;s ids&lt;br /&gt;
** table_row - for searching a table row which contains the specified text&lt;br /&gt;
** table - for searching a table by its id or caption&lt;br /&gt;
** fieldset - for searching a fieldset by it&#039;s id or legend&lt;br /&gt;
** css_element - for searching an element by its CSS selector&lt;br /&gt;
** xpath_element - for searching an element by its XPath&lt;br /&gt;
&lt;br /&gt;
====== Checking table values ======&lt;br /&gt;
You can check if specific value exists or not in a table row/column by using:&lt;br /&gt;
* Then &amp;quot;STRING_IN_ROW&amp;quot; row &amp;quot;COLUMN_HEADER&amp;quot; column of &amp;quot;TABLE_ID&amp;quot; table should contain &amp;quot;VALUE_TO_CHECK&amp;quot;&lt;br /&gt;
* Then the following should exist in the &amp;quot;TABLE_ID&amp;quot; table:&lt;br /&gt;
    | COLUMN_HEADER1 | COLUMN_HEADER2 |&lt;br /&gt;
    | VALUE_IN_ROW_1 | VALUE_IN_ROW_1 |&lt;br /&gt;
    | VALUE_IN_ROW_2 | VALUE_IN_ROW_2 |&lt;br /&gt;
&lt;br /&gt;
==== Advanced use cases ====&lt;br /&gt;
Most of the time the usage of existing step definitions is straight forward. However, there are some exceptions were it might get complicated. Some of them are listed here:&lt;br /&gt;
&lt;br /&gt;
====== Uploading files ======&lt;br /&gt;
Note than some tests requires files to be uploaded, in this case&lt;br /&gt;
* The &#039;&#039;&#039;I upload &amp;quot;FILEPATH_STRING&amp;quot; file to &amp;quot;FILEPICKER_FIELD_STRING&amp;quot; filepicker&#039;&#039;&#039; step can be used when located in the form page&lt;br /&gt;
* The file to upload should be included along with the Moodle codebase in COMPONENTNAME/tests/fixtures/*&lt;br /&gt;
* The file to upload is specified by it&#039;s path, which should be relative to the codebase root (&#039;&#039;&#039;lib/tests/fixtures/users.csv&#039;&#039;&#039; for example) &lt;br /&gt;
* &#039;&#039;&#039;/&#039;&#039;&#039; should be used as directory separator and the file names can not include this &#039;&#039;&#039;/&#039;&#039;&#039; character as all of them would be converted to the OS-dependant directory separator to maintain the compatibility with Windows systems.&lt;br /&gt;
* The scenarios that includes files uploading should be tagged using the &#039;&#039;&#039;@_file_upload&#039;&#039;&#039; tag&lt;br /&gt;
&amp;lt;code behat&amp;gt;&lt;br /&gt;
@editor @editor_atto @atto @atto_media @_file_upload&lt;br /&gt;
Feature: Add media to Atto&lt;br /&gt;
  To write rich text - I need to add media.&lt;br /&gt;
&lt;br /&gt;
  Background:&lt;br /&gt;
    Given I log in as &amp;quot;admin&amp;quot;&lt;br /&gt;
    And I follow &amp;quot;Manage private files...&amp;quot;&lt;br /&gt;
    And I upload &amp;quot;lib/editor/atto/tests/fixtures/moodle-logo.webm&amp;quot; file to &amp;quot;Files&amp;quot; filemanager&lt;br /&gt;
    And I upload &amp;quot;lib/editor/atto/tests/fixtures/moodle-logo.mp4&amp;quot; file to &amp;quot;Files&amp;quot; filemanager&lt;br /&gt;
    And I upload &amp;quot;lib/editor/atto/tests/fixtures/moodle-logo.png&amp;quot; file to &amp;quot;Files&amp;quot; filemanager&lt;br /&gt;
    And I upload &amp;quot;lib/editor/atto/tests/fixtures/pretty-good-en.vtt&amp;quot; file to &amp;quot;Files&amp;quot; filemanager&lt;br /&gt;
    And I upload &amp;quot;lib/editor/atto/tests/fixtures/pretty-good-sv.vtt&amp;quot; file to &amp;quot;Files&amp;quot; filemanager&lt;br /&gt;
    And I click on &amp;quot;Save changes&amp;quot; &amp;quot;button&amp;quot;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Field groups ======&lt;br /&gt;
This section describes how you can use the step definitions&lt;br /&gt;
&amp;lt;code behat&amp;gt;&lt;br /&gt;
When I set the following fields to these values:&lt;br /&gt;
...&lt;br /&gt;
When I set the field &amp;quot;([^&amp;quot;]|\&amp;quot;*)&amp;quot; to &amp;quot;([^&amp;quot;]|\&amp;quot;*)&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
for field groups. Examples for such field groups are the duration field or the date_time_selector. These are not displayed as one single input field within the front-end but consist of multiple input fields within one row.&lt;br /&gt;
You can access each single input field of a group using &lt;br /&gt;
&amp;lt;code behat&amp;gt;&lt;br /&gt;
identifierOfYourField[keyOfTheSpecificInput]&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Examples would be:&lt;br /&gt;
&amp;lt;code behat&amp;gt;&lt;br /&gt;
When I set the following fields to these values:&lt;br /&gt;
  | myDate[day]             |   21   |&lt;br /&gt;
  | myDate[month]           |   12   |&lt;br /&gt;
  | myDate[hour]            |   14   |&lt;br /&gt;
  | myDuration[number]      |   10   |&lt;br /&gt;
  | myDuration[unit]        | days   |&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Human-readable and relative dates ======&lt;br /&gt;
When testing plugins with deadlines, for instance for submissions, it is often necessary to set certain time values to dates relative to today.&lt;br /&gt;
You can specify a relative time enclosed within two ## blocks. For example:&lt;br /&gt;
* ## yesterday ##&lt;br /&gt;
* ## 2 days ago ##&lt;br /&gt;
You can use everything according to [http://php.net/manual/en/datetime.formats.php].&lt;br /&gt;
&lt;br /&gt;
Especially useful are the relative formats from: [http://php.net/manual/en/datetime.formats.relative.php]&lt;br /&gt;
&lt;br /&gt;
Additionally, you can specify a format you want the date to be returned into:&lt;br /&gt;
* ## yesterday ## myformat ##&lt;br /&gt;
These formats can be used as outlined in [http://php.net/manual/en/function.date.php].&lt;br /&gt;
This can be combined with the field groups:&lt;br /&gt;
&amp;lt;code behat&amp;gt;&lt;br /&gt;
When I set the following fields to these values:&lt;br /&gt;
  | myDate[day]             |   ## yesterday ## j ##   |&lt;br /&gt;
  | myDate[month]           |   ## yesterday ## n ##   |&lt;br /&gt;
  | myDate[year]            |   ## yesterday ## Y ##   |&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Good practice ==&lt;br /&gt;
&lt;br /&gt;
=== Test one thing per scenario ===&lt;br /&gt;
&lt;br /&gt;
The ideal that you should strive for, is that each scenario tests just one specific bit of functionality. Therefore, if one test fails, the scenario name should tell you exactly what the bug is. Also, any bug should cause just one scenario to fail, not lots of unrelated ones. If you can achieve this, then the idea is that it minimises the time from seeing a test fail to having fixed the bug that was detected. Of course, this ideal is not always achievable, but in my experience it is worth striving for.&lt;br /&gt;
&lt;br /&gt;
=== Set-up (Given) should not use the UI ===&lt;br /&gt;
&lt;br /&gt;
The setup is not what you are really testing here. Therefore, it should be as quick and reliable as possible. The way to achieve this is with steps like &amp;lt;tt&amp;gt;And the following &amp;quot;Thing&amp;quot; exist:&amp;lt;/tt&amp;gt; which directly insert the data into the database. If necessary, write extra steps for your plugin to setup the things you need.&lt;br /&gt;
&lt;br /&gt;
=== Don&#039;t use XPath or CSS selectors - fix your Accessibility bugs ===&lt;br /&gt;
&lt;br /&gt;
If, the only way you can identify something in the page that you want to manipulate is with a step like &amp;lt;tt&amp;gt;I set the field with xpath &amp;quot;//textarea[contains(@name, &#039;answer&#039;)]&amp;quot; to &amp;quot;frog&amp;quot;&amp;lt;/tt&amp;gt;, then this is probably the sign that you have an Accessibility bug, because Behat accesses the page very like a screen-reader user would.&lt;br /&gt;
&lt;br /&gt;
You should be able to refer to things with steps like &amp;lt;tt&amp;gt;I set the field &amp;quot;Answer&amp;quot; to &amp;quot;frog&amp;quot;&#039;&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;I click on &amp;quot;True&amp;quot; &amp;quot;radio&amp;quot; in the &amp;quot;First question&amp;quot; &amp;quot;question&amp;quot;&amp;lt;/tt&amp;gt;. If not, you should probably think about fixing the accessibility bug, rather than resorting to unreadable selectors in your Behat test.&lt;br /&gt;
&lt;br /&gt;
=== When you define more steps in your plugin, make it clear they come from your plugin ===&lt;br /&gt;
&lt;br /&gt;
When defining new Step definitions in your plugin, try to make sure the step name identifies it as belonging to your plugin. So, don&#039;t make a step called &amp;lt;tt&amp;gt;I disable UI plugins&amp;lt;/tt&amp;gt;. Call it something like &amp;lt;tt&amp;gt;I disable UI plugins in the CodeRunner question type&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Category:Behat]]&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Acceptance_testing&amp;diff=55585</id>
		<title>Acceptance testing</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Acceptance_testing&amp;diff=55585"/>
		<updated>2019-02-14T14:50:30Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: Missing category&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is a starting point for working with acceptance tests (behat tests). These tests are suited if you want to test the front-end and with that the behaviour of your site / your plugin / your code.&lt;br /&gt;
&lt;br /&gt;
If you want to write your own tests have a look at: [[Writing acceptance tests]]&lt;br /&gt;
&lt;br /&gt;
If you want to run behat tests of the existing suite or the ones you have written for your own plugin please visit: [[Running acceptance test]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Behat]]&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=User:Ruslan_Kabalin&amp;diff=55020</id>
		<title>User:Ruslan Kabalin</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=User:Ruslan_Kabalin&amp;diff=55020"/>
		<updated>2018-11-19T14:21:16Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;For details, please see my profile on [https://moodle.org/user/profile.php?id=23389 moodle.org].&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Writing_acceptance_tests&amp;diff=54974</id>
		<title>Writing acceptance tests</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Writing_acceptance_tests&amp;diff=54974"/>
		<updated>2018-11-09T11:54:18Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: Add useful information about steps, it has been located in the old version of Acceptance_testing document, but still useful as this is not covered anywhere. Might be not complete though, but at least something.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
This documentation gives some hints, how to write behat tests for core and for plugins.&lt;br /&gt;
The focus of the documentation is on behat tests for plugins.&lt;br /&gt;
They are written in some kind of natural language and describe how the front-end of moodle should behave, when a user interacts with it.&lt;br /&gt;
Each test consists of a set of so called steps in a GIVEN, WHEN, THEN style:&lt;br /&gt;
* &#039;&#039;&#039;GIVEN&#039;&#039;&#039;: These steps outline the state of your moodle platform at the start of your test. Here you can create users, courses and plugin instances.&lt;br /&gt;
* &#039;&#039;&#039;WHEN&#039;&#039;&#039;: These steps usually execute the functionality of your plugin, which is under test.&lt;br /&gt;
* &#039;&#039;&#039;THEN&#039;&#039;&#039;: These steps describe the expected behaviour of your plugin. They usually check if different elements can or can&#039;t be seen.&lt;br /&gt;
&lt;br /&gt;
To initialize and run your tests, please follow the instructions of [[Running_acceptance_test]].&lt;br /&gt;
&lt;br /&gt;
== Create you own tests ==&lt;br /&gt;
Behat tests are located within the directory tests/behat of your plugin.&lt;br /&gt;
The different tests are defined in files with the ending *.feature.&lt;br /&gt;
First, you have to define the header of your test:&lt;br /&gt;
&amp;lt;code behat&amp;gt;&lt;br /&gt;
@mod @mod_yourplugin @javascript&lt;br /&gt;
Feature: Here comes a description of your user story.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The tags on top of the feature description can be used to select specific test cases when running the tests.&lt;br /&gt;
The &#039;@javascript&#039; tag should only be used, if javascript is needed to execute your test. This is dependent on the step you will use in your definition.&lt;br /&gt;
Javascript tests are usually much slower than tests executed without javascript.&lt;br /&gt;
&lt;br /&gt;
Afterwards you can specify a scenario:&lt;br /&gt;
&amp;lt;code behat&amp;gt;&lt;br /&gt;
@javascript&lt;br /&gt;
  Scenario: Description of your scenario, which you want to test.&lt;br /&gt;
    When I log in as &amp;quot;student1&amp;quot;&lt;br /&gt;
    And I am on &amp;quot;Course 1&amp;quot; course homepage&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Again you can define specific tags. Afterwards you write the steps, which should be executed during your test.&lt;br /&gt;
&lt;br /&gt;
==== Multiple Scenarios ====&lt;br /&gt;
You can have an arbitrary amount of scenarios within a test. Please make sure they all belong to the same feature.&lt;br /&gt;
If you have certain steps, which should be executed for every scenario of a feature, you can define them using a background:&lt;br /&gt;
&amp;lt;code behat&amp;gt;&lt;br /&gt;
Background:&lt;br /&gt;
    Given the following &amp;quot;courses&amp;quot; exist:&lt;br /&gt;
      | fullname | shortname | category | groupmode |&lt;br /&gt;
      | Course 1 | C1        | 0        | 1         |&lt;br /&gt;
    And the following &amp;quot;users&amp;quot; exist:&lt;br /&gt;
      | username | firstname | lastname | email |&lt;br /&gt;
      | teacher1 | Theo | Teacher | teacher1@example.com |&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This is usually used, to define the different &#039;&#039;&#039;GIVEN&#039;&#039;&#039; steps.&lt;br /&gt;
&lt;br /&gt;
==== Use existing steps ====&lt;br /&gt;
There are different ways how to effectively browse the available existing steps:&lt;br /&gt;
&lt;br /&gt;
====== Moodle Administration ======&lt;br /&gt;
Moodle offers within its administration menu under Site Administration &amp;gt; Development &amp;gt; Acceptance Testing a complete and searchable list of all available step definitions.&lt;br /&gt;
However, make sure you installed the behat test site first!&lt;br /&gt;
&lt;br /&gt;
====== PhpStorm ======&lt;br /&gt;
In PhpStorm or IntelliJ you can install the behat extension. Then you get auto completions within feature files, which helps a lot during behat test development.&lt;br /&gt;
&lt;br /&gt;
==== Providing values to steps ====&lt;br /&gt;
Most of the steps requires values, there are methods to provide values to steps, the method depends on the step specification.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;A string/text&#039;&#039;&#039;; is the most common case, the texts are wrapped between double quotes (&amp;quot; character) you have to replace the info about the expected value for your value; for example something like &#039;&#039;&#039;I press &amp;quot;BUTTON_STRING&amp;quot;&#039;&#039;&#039; should become &#039;&#039;&#039;I press &amp;quot;Save and return to course&amp;quot;&#039;&#039;&#039;. If you want to add a string which contains a &amp;quot; character, you can escape it with \&amp;quot;, for example &#039;&#039;&#039;I fill the &amp;quot;Name&amp;quot; field with &amp;quot;Alan alias \&amp;quot;the legend\&amp;quot;&amp;quot;&#039;&#039;&#039;. You can identify this steps because they ends with &#039;&#039;&#039;_STRING&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;A number&#039;&#039;&#039;; some steps requires numbers as values, to be more specific an undetermined number of digits from 0 to 9 (Natural numbers + 0) you can identify them because the expected value info string ends with &#039;&#039;&#039;_NUMBER&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;A table&#039;&#039;&#039;; is a relation between values, the most common use of it is to fill forms. The steps which requires tables are easily identifiable because they finish with &#039;&#039;&#039;:&#039;&#039;&#039; The steps description gives info about what the table columns must contain, for example &#039;&#039;&#039;Fills a moodle form with field/value data&#039;&#039;&#039;. Here you don&#039;t need to escape the double quotes if you want to include them as part of the value.&lt;br /&gt;
* &#039;&#039;&#039;A PyString&#039;&#039;&#039;; is a multiline string, most commonly used to fill out forms when a newline is required. Like steps with tables, steps which require PyStrings will end with &amp;quot;:&amp;quot;&lt;br /&gt;
* &#039;&#039;&#039;A field value&#039;&#039;&#039;; There are many different field types, if an argument requires a field value the expected value will depend on the field type:&lt;br /&gt;
** Text-based fields: It expects the text. This includes textareas, input type text, input type password...&lt;br /&gt;
** Checkbox: It expects 1 to check and for checked and &amp;quot;&amp;quot; to uncheck or for unchecked&lt;br /&gt;
** Select: It expects the option text or the option value. In case you interact with a multi-select you should specify the options separating them with commas. For example: &#039;&#039;&#039;option1, option2, option3&#039;&#039;&#039;&lt;br /&gt;
** Radio: The text of the radio option&lt;br /&gt;
* &#039;&#039;&#039;A selector&#039;&#039;&#039;; there are steps that can be used with different kinds of elements, for example &#039;&#039;&#039;I click on &amp;quot;User Name&amp;quot; &amp;quot;link&amp;quot;&#039;&#039;&#039; or &#039;&#039;&#039;I click on &amp;quot;User Name&amp;quot; &amp;quot;button&amp;quot;&#039;&#039;&#039; this is a closed list of elements, they always works together with another argument, where you specify the locator (eg. the link text in a link) In the &#039;Acceptance testing&#039; interface you can see a drop-down menu to select one of these options:&lt;br /&gt;
** field - for searching a field by its id, name, value or label&lt;br /&gt;
** link - for searching a link by its href, id, title, img alt or value&lt;br /&gt;
** button - for searching a button by its name, id, value, img alt or title&lt;br /&gt;
** link_or_button - for searching for both, links and buttons&lt;br /&gt;
** select - for searching a select field by its id, name or label&lt;br /&gt;
** checkbox - for searching a checkbox by its id, name, or label&lt;br /&gt;
** radio - for searching a radio button by its id, name, or label&lt;br /&gt;
** file - for searching a file input by its id, name, or label&lt;br /&gt;
** optgroup - for searching optgroup by its label&lt;br /&gt;
** option - for searching an option by its content&lt;br /&gt;
** dialogue - for searching a dialogue with the specified header text&lt;br /&gt;
** filemanager - for searching a filemanager by it&#039;s id or label&lt;br /&gt;
** block - for searching a Moodle block by it&#039;s English name or it&#039;s frankenstyle name&lt;br /&gt;
** section - for searching for a section on a course page by it&#039;s title or its written out date (e.g. &amp;quot;1 January - 7 January&amp;quot;). Use &amp;quot;frontpage&amp;quot; &amp;quot;section&amp;quot; for the frontpage section if it has no title (default)&lt;br /&gt;
** activity - for searching for an activity module in a course list by it&#039;s title&lt;br /&gt;
** region - for searching a Moodle page region with that id, in fact it works with all the page&#039;s ids&lt;br /&gt;
** table_row - for searching a table row which contains the specified text&lt;br /&gt;
** table - for searching a table by its id or caption&lt;br /&gt;
** fieldset - for searching a fieldset by it&#039;s id or legend&lt;br /&gt;
** css_element - for searching an element by its CSS selector&lt;br /&gt;
** xpath_element - for searching an element by its XPath&lt;br /&gt;
* &#039;&#039;&#039;A text selector&#039;&#039;&#039;; similar to a selector but those are the elements that returns an area of the DOM, they are useful in steps following the format &#039;&#039;&#039;... in the &amp;quot;Community finder&amp;quot; &amp;quot;block&amp;quot;&#039;&#039;&#039; where you are clicking or looking for some text inside a specific area. In the &#039;Acceptance testing&#039; interface you can see a drop-down menu to select one of these options:&lt;br /&gt;
** dialogue - for searching a dialogue with the specified header text&lt;br /&gt;
** block - for searching a Moodle block by it&#039;s English name or it&#039;s frankenstyle name&lt;br /&gt;
** section - for searching for a section on a course page by it&#039;s title or its written out date (e.g. &amp;quot;1 January - 7 January&amp;quot;). Use &amp;quot;frontpage&amp;quot; &amp;quot;section&amp;quot; for the frontpage section if it has no title (default)&lt;br /&gt;
** activity - for searching for an activity module in a course list by it&#039;s title&lt;br /&gt;
** region - for searching a Moodle page region with that id, in fact it works with all the page&#039;s ids&lt;br /&gt;
** table_row - for searching a table row which contains the specified text&lt;br /&gt;
** table - for searching a table by its id or caption&lt;br /&gt;
** fieldset - for searching a fieldset by it&#039;s id or legend&lt;br /&gt;
** css_element - for searching an element by its CSS selector&lt;br /&gt;
** xpath_element - for searching an element by its XPath&lt;br /&gt;
&lt;br /&gt;
====== Checking table values ======&lt;br /&gt;
You can check if specific value exists or not in a table row/column by using:&lt;br /&gt;
* Then &amp;quot;STRING_IN_ROW&amp;quot; row &amp;quot;COLUMN_HEADER&amp;quot; column of &amp;quot;TABLE_ID&amp;quot; table should contain &amp;quot;VALUE_TO_CHECK&amp;quot;&lt;br /&gt;
* Then the following should exist in the &amp;quot;TABLE_ID&amp;quot; table:&lt;br /&gt;
    | COLUMN_HEADER1 | COLUMN_HEADER2 |&lt;br /&gt;
    | VALUE_IN_ROW_1 | VALUE_IN_ROW_1 |&lt;br /&gt;
    | VALUE_IN_ROW_2 | VALUE_IN_ROW_2 |&lt;br /&gt;
&lt;br /&gt;
==== Advanced use cases ====&lt;br /&gt;
Most of the time the usage of existing step definitions is straight forward. However, there are some exceptions were it might get complicated. Some of them are listed here:&lt;br /&gt;
&lt;br /&gt;
====== Uploading files ======&lt;br /&gt;
Note than some tests requires files to be uploaded, in this case&lt;br /&gt;
* The &#039;&#039;&#039;I upload &amp;quot;FILEPATH_STRING&amp;quot; file to &amp;quot;FILEPICKER_FIELD_STRING&amp;quot; filepicker&#039;&#039;&#039; step can be used when located in the form page&lt;br /&gt;
* The file to upload should be included along with the Moodle codebase in COMPONENTNAME/tests/fixtures/*&lt;br /&gt;
* The file to upload is specified by it&#039;s path, which should be relative to the codebase root (&#039;&#039;&#039;lib/tests/fixtures/users.csv&#039;&#039;&#039; for example) &lt;br /&gt;
* &#039;&#039;&#039;/&#039;&#039;&#039; should be used as directory separator and the file names can not include this &#039;&#039;&#039;/&#039;&#039;&#039; character as all of them would be converted to the OS-dependant directory separator to maintain the compatibility with Windows systems.&lt;br /&gt;
* The scenarios that includes files uploading should be tagged using the &#039;&#039;&#039;@_file_upload&#039;&#039;&#039; tag&lt;br /&gt;
&amp;lt;code behat&amp;gt;&lt;br /&gt;
@editor @editor_atto @atto @atto_media @_file_upload&lt;br /&gt;
Feature: Add media to Atto&lt;br /&gt;
  To write rich text - I need to add media.&lt;br /&gt;
&lt;br /&gt;
  Background:&lt;br /&gt;
    Given I log in as &amp;quot;admin&amp;quot;&lt;br /&gt;
    And I follow &amp;quot;Manage private files...&amp;quot;&lt;br /&gt;
    And I upload &amp;quot;lib/editor/atto/tests/fixtures/moodle-logo.webm&amp;quot; file to &amp;quot;Files&amp;quot; filemanager&lt;br /&gt;
    And I upload &amp;quot;lib/editor/atto/tests/fixtures/moodle-logo.mp4&amp;quot; file to &amp;quot;Files&amp;quot; filemanager&lt;br /&gt;
    And I upload &amp;quot;lib/editor/atto/tests/fixtures/moodle-logo.png&amp;quot; file to &amp;quot;Files&amp;quot; filemanager&lt;br /&gt;
    And I upload &amp;quot;lib/editor/atto/tests/fixtures/pretty-good-en.vtt&amp;quot; file to &amp;quot;Files&amp;quot; filemanager&lt;br /&gt;
    And I upload &amp;quot;lib/editor/atto/tests/fixtures/pretty-good-sv.vtt&amp;quot; file to &amp;quot;Files&amp;quot; filemanager&lt;br /&gt;
    And I click on &amp;quot;Save changes&amp;quot; &amp;quot;button&amp;quot;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Field groups ======&lt;br /&gt;
This section describes how you can use the step definitions&lt;br /&gt;
&amp;lt;code behat&amp;gt;&lt;br /&gt;
When I set the following fields to these values:&lt;br /&gt;
...&lt;br /&gt;
When I set the field &amp;quot;([^&amp;quot;]|\&amp;quot;*)&amp;quot; to &amp;quot;([^&amp;quot;]|\&amp;quot;*)&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
for field groups. Examples for such field groups are the duration field or the date_time_selector. These are not displayed as one single input field within the front-end but consist of multiple input fields within one row.&lt;br /&gt;
You can access each single input field of a group using &lt;br /&gt;
&amp;lt;code behat&amp;gt;&lt;br /&gt;
identifierOfYourField[keyOfTheSpecificInput]&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Examples would be:&lt;br /&gt;
&amp;lt;code behat&amp;gt;&lt;br /&gt;
When I set the following fields to these values:&lt;br /&gt;
  | myDate[day]             |   21   |&lt;br /&gt;
  | myDate[month]           |   12   |&lt;br /&gt;
  | myDate[hour]            |   14   |&lt;br /&gt;
  | myDuration[number]      |   10   |&lt;br /&gt;
  | myDuration[unit]        | days   |&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Relative dates ======&lt;br /&gt;
When testing plugins with deadlines, for instance for submissions, it is often necessary to set certain time values to dates relative to today.&lt;br /&gt;
You can specify a relative time enclosed within two ## blocks. For example:&lt;br /&gt;
* ## yesterday ##&lt;br /&gt;
* ## 2 days ago ##&lt;br /&gt;
You can use everything according to [http://php.net/manual/en/datetime.formats.php].&lt;br /&gt;
&lt;br /&gt;
Especially useful are the relative formats from: [http://php.net/manual/en/datetime.formats.relative.php]&lt;br /&gt;
&lt;br /&gt;
Additionally, you can specify a format you want the date to be returned into:&lt;br /&gt;
* ## yesterday ## myformat ##&lt;br /&gt;
These formats can be used as outlined in [http://php.net/manual/en/function.date.php].&lt;br /&gt;
This can be combined with the field groups:&lt;br /&gt;
&amp;lt;code behat&amp;gt;&lt;br /&gt;
When I set the following fields to these values:&lt;br /&gt;
  | myDate[day]             |   ## yesterday ## j ##   |&lt;br /&gt;
  | myDate[month]           |   ## yesterday ## n ##   |&lt;br /&gt;
  | myDate[year]            |   ## yesterday ## Y ##   |&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Grunt&amp;diff=54854</id>
		<title>Grunt</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Grunt&amp;diff=54854"/>
		<updated>2018-10-12T10:14:36Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: /* Running grunt: add info on verbose param */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.9}}&lt;br /&gt;
&lt;br /&gt;
Grunt is a command line tool used to prepare our javascript and less-generated css for production usage. After making any change to javascript or less files in Moodle, you must run grunt to lint, minify and package the javascript/css properly so that it can be served by Moodle.&lt;br /&gt;
&lt;br /&gt;
== Install grunt ==&lt;br /&gt;
The Javascript modules (AMD and YUI) and less css in Moodle must be processed by some build tools before they will be visible to your web browser. We use &amp;quot;[http://gruntjs.com/ grunt]&amp;quot; as a build tool to wrap our different processes. Grunt is a build tool written in Javascript that runs in the &amp;quot;[http://nodejs.org/ nodejs]&amp;quot; environment. This means you first have to install nodejs - and it&#039;s package manager &amp;quot;[https://www.npmjs.com/ npm]&amp;quot;. The details of how to install those packages will vary by operating system, but on Linux it&#039;s likely to be: &lt;br /&gt;
 apt-get install nodejs npm&lt;br /&gt;
See also: [http://askubuntu.com/questions/594656/how-to-install-the-latest-versions-of-nodejs-and-npm-for-ubuntu-14-04-lts/711976 how to install the latest version of nodejs and npm for ubuntu 14.04]&lt;br /&gt;
&lt;br /&gt;
There are downloadable packages for other operating systems here: http://nodejs.org/download/. &lt;br /&gt;
&lt;br /&gt;
Once this is done, cd into your Moodle directory and run the command: &lt;br /&gt;
 npm install&lt;br /&gt;
to install all of the required tools.&lt;br /&gt;
&lt;br /&gt;
You also need to install the grunt-cli package globally in order to have a &amp;quot;grunt&amp;quot; command in your path. To do this run:&lt;br /&gt;
 npm install -g grunt-cli&lt;br /&gt;
&lt;br /&gt;
== Running grunt ==&lt;br /&gt;
Typical commands:&lt;br /&gt;
&lt;br /&gt;
 grunt amd               # Short-cut for grunt jshint uglify, rebuild all AMD modules.&lt;br /&gt;
 grunt shifter           # Run shifter&lt;br /&gt;
 grunt js                # Short-cut for grunt amd shifter&lt;br /&gt;
 &lt;br /&gt;
 grunt css               # Run less&lt;br /&gt;
 grunt                   # Try to do the right thing:&lt;br /&gt;
                         # * If you are in a folder called amd, do grunt amd&lt;br /&gt;
                         # * If you are in a folder called yui/src/something, do grunt shifter&lt;br /&gt;
                         # * Otherwise build everything (grunt css js).&lt;br /&gt;
 &lt;br /&gt;
 grunt watch             # Watch for changes and re-run grunt tasks depending on what file changes&lt;br /&gt;
 grunt eslint --show-lint-warnings # Show pedantic lint warnings for JS&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
On Linux/Mac it will build everything in the current folder and below. You need to cd into the amd folder of your module root, i.e. &amp;lt;tt&amp;gt;dirroot/blocks/foo/amd&amp;lt;/tt&amp;gt; before running &amp;lt;tt&amp;gt;grunt amd&amp;lt;/tt&amp;gt; - this will compile only your plugins AMD source files. You can make output more verbose by adding &amp;lt;tt&amp;gt;-v&amp;lt;/tt&amp;gt; parameter, if used with &amp;lt;tt&amp;gt;grunt shifter&amp;lt;/tt&amp;gt; this will actually show what your lint errors are. On Windows, you need to specify the path on the command line like &amp;lt;tt&amp;gt;--root=admin/tool/templatelibrary&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Using Grunt in additional plugins ==&lt;br /&gt;
&lt;br /&gt;
You may want to use Grunt for performing tasks in your custom Moodle plugins. For building AMD and YUI modules in your plugin, the standard configuration Gruntfile.js located in the Moodle root should work well. For building CSS files from LESS templates, you will have to set up a separate Grunt installation in the root of your plugin.&lt;br /&gt;
&lt;br /&gt;
If you do not have it yet, create the package.json file in the root of your plugin:&lt;br /&gt;
&lt;br /&gt;
    {&lt;br /&gt;
        &amp;quot;name&amp;quot;: &amp;quot;moodle-plugintype_pluginname&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
Install grunt, grunt less and grunt watch modules. Note that you should put the folder node_modules into your plugin&#039;s .gitignore file, too.&lt;br /&gt;
&lt;br /&gt;
    $ cd /path/to/your/plugin/root&lt;br /&gt;
    $ npm install --save-dev grunt grunt-contrib-less grunt-contrib-watch grunt-load-gruntfile&lt;br /&gt;
&lt;br /&gt;
Create a Gruntfile.js in the root of your plugin and configure the task for building CSS files from LESS:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
&amp;quot;use strict&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
module.exports = function (grunt) {&lt;br /&gt;
&lt;br /&gt;
    // We need to include the core Moodle grunt file too, otherwise we can&#039;t run tasks like &amp;quot;amd&amp;quot;.&lt;br /&gt;
    require(&amp;quot;grunt-load-gruntfile&amp;quot;)(grunt);&lt;br /&gt;
    grunt.loadGruntfile(&amp;quot;../../Gruntfile.js&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    // Load all grunt tasks.&lt;br /&gt;
    grunt.loadNpmTasks(&amp;quot;grunt-contrib-less&amp;quot;);&lt;br /&gt;
    grunt.loadNpmTasks(&amp;quot;grunt-contrib-watch&amp;quot;);&lt;br /&gt;
    grunt.loadNpmTasks(&amp;quot;grunt-contrib-clean&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    grunt.initConfig({&lt;br /&gt;
        watch: {&lt;br /&gt;
            // If any .less file changes in directory &amp;quot;less&amp;quot; then run the &amp;quot;less&amp;quot; task.&lt;br /&gt;
            files: &amp;quot;less/*.less&amp;quot;,&lt;br /&gt;
            tasks: [&amp;quot;less&amp;quot;]&lt;br /&gt;
        },&lt;br /&gt;
        less: {&lt;br /&gt;
            // Production config is also available.&lt;br /&gt;
            development: {&lt;br /&gt;
                options: {&lt;br /&gt;
                    // Specifies directories to scan for @import directives when parsing.&lt;br /&gt;
                    // Default value is the directory of the source, which is probably what you want.&lt;br /&gt;
                    paths: [&amp;quot;less/&amp;quot;],&lt;br /&gt;
                    compress: true&lt;br /&gt;
                },&lt;br /&gt;
                files: {&lt;br /&gt;
                    &amp;quot;styles.css&amp;quot;: &amp;quot;less/styles.less&amp;quot;&lt;br /&gt;
                }&lt;br /&gt;
            },&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
    // The default task (running &amp;quot;grunt&amp;quot; in console).&lt;br /&gt;
    grunt.registerTask(&amp;quot;default&amp;quot;, [&amp;quot;less&amp;quot;]);&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now running &amp;quot;grunt&amp;quot; or &amp;quot;grunt less&amp;quot; in your plugin root folder will compile the file less/styles.less and saves it as styles.css. Running &amp;quot;grunt watch&amp;quot; will watch the less/*.less files and if some is changed, it will immediately rebuild the CSS file.&lt;br /&gt;
&lt;br /&gt;
If you are working on a custom theme, you may have multiple less/*.less files that you want to compile to their style/*.css counterparts. You can either define an explicit list all such file pairs, or let that list be created for you by making use of [http://gruntjs.com/configuring-tasks#building-the-files-object-dynamically expand:true feature] of gruntfile.js:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
// This dynamically creates the list of files to be processed.&lt;br /&gt;
files: [&lt;br /&gt;
    {   &lt;br /&gt;
        expand: true,&lt;br /&gt;
        cwd: &amp;quot;less/&amp;quot;,&lt;br /&gt;
        src: &amp;quot;*.less&amp;quot;,&lt;br /&gt;
        dest: &amp;quot;style/&amp;quot;,&lt;br /&gt;
        ext: &amp;quot;.css&amp;quot;&lt;br /&gt;
    }   &lt;br /&gt;
]   &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [[YUI/Shifter]]&lt;br /&gt;
* [[Javascript Modules]]&lt;br /&gt;
* [[LESS]]&lt;br /&gt;
&lt;br /&gt;
[[Category:AJAX]]&lt;br /&gt;
[[Category:Javascript]]&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Developer_notes&amp;diff=54099</id>
		<title>Developer notes</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Developer_notes&amp;diff=54099"/>
		<updated>2018-05-01T10:48:33Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: /* Other */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This area is for developers to work on various bits of code and documentation as necessary. Once material has matured it should be linked to from the main [[Developer documentation|Developer documentation]] page.&lt;br /&gt;
&lt;br /&gt;
==Core code==&lt;br /&gt;
&lt;br /&gt;
*[[Other lang issues|Language issues]] &lt;br /&gt;
*[[Datalib Notes]]&lt;br /&gt;
*[[Application/session variables]]&lt;br /&gt;
*[[Filters schema]]&lt;br /&gt;
*[[Filterall support]]&lt;br /&gt;
*[[Groups documentation for module developers]]&lt;br /&gt;
*[[Plan to improve ability to delegate administrator tasks to course category level|Plan to improve ability to delegate administrator tasks to course category level]]&lt;br /&gt;
*[[Stealth mode and nested activities|Stealth mode and nested activities]]&lt;br /&gt;
*[[Enrolment_plugins_2.0|How enrolments should work in Moodle 2.0]]&lt;br /&gt;
*[[Redesigning the override roles page|Redesigning the override roles page]]&lt;br /&gt;
&lt;br /&gt;
===Gradebook===&lt;br /&gt;
&lt;br /&gt;
*[[Gradebook_improvements|Gradebook improvements]] - ideas from Petr.&lt;br /&gt;
*[[Tim&#039;s_Gradebook_thoughts|Tim&#039;s Gradebook thoughts]]&lt;br /&gt;
&lt;br /&gt;
==Modules and other recognised plugin types==&lt;br /&gt;
&lt;br /&gt;
===Lesson===&lt;br /&gt;
&lt;br /&gt;
*[[Adding_question_types_to_lesson|Adding question types to lesson module]]&lt;br /&gt;
*[[New lesson navigation | New lesson navigation]]&lt;br /&gt;
*[[Adding blocks to lesson | Adding blocks to lesson]]&lt;br /&gt;
&lt;br /&gt;
===Quiz &amp;amp; question types===&lt;br /&gt;
&lt;br /&gt;
* [[File storage conversion Quiz and Questions|File storage conversion Quiz and Questions]] - notes for MDL-16094.&lt;br /&gt;
* [[How the quiz navigation should work in Moodle 2.0|How the quiz navigation should work in Moodle 2.0]] - MDL-20276.&lt;br /&gt;
* [[Moodle 2.0 question bank improvements|Moodle 2.0 question bank improvements]] - including question tagging and improved searchability.&lt;br /&gt;
* [[Question_Engine_2|Proposal to change the Moodle Question Engine]] This supersedes &lt;br /&gt;
** [[Plans for adaptive mode|Plans for adaptive mode]]&lt;br /&gt;
** [[Implementation of true negative marks in MC-type questions|Implementation of true negative marks in MC-type questions]]&lt;br /&gt;
* [[Calculated question : adding new math functions]]&lt;br /&gt;
* [[Numerical question units and intervals]]&lt;br /&gt;
* [[Future question bank/sharing/versioning requirements|Future question bank/sharing/versioning requirements]]&lt;br /&gt;
* [[States of a quiz attempt]]&lt;br /&gt;
* [[Optional checkbox &amp;quot;This is all my own work&amp;quot; before submitting a quiz]]&lt;br /&gt;
* [[The OU PMatch algorithm]]&lt;br /&gt;
* [[Provide print option for a Quiz]]&lt;br /&gt;
&lt;br /&gt;
===Other activity modules===&lt;br /&gt;
&lt;br /&gt;
*[[Forum development|Forum functional upgrade]]&lt;br /&gt;
*[[Wiki development|Wiki module development]]&lt;br /&gt;
*[[Schedule development|Proposed replacement for Scheduler]]&lt;br /&gt;
&lt;br /&gt;
===Gradebook Plugins===&lt;br /&gt;
&lt;br /&gt;
*[[External Database Plugin]]&lt;br /&gt;
&lt;br /&gt;
===Other===&lt;br /&gt;
&lt;br /&gt;
*[[Blogs and forums|Blogs, forums and the nature of discussion]]&lt;br /&gt;
*[[Conditional activities]]&lt;br /&gt;
*[[Improved Payment Plugin]]&lt;br /&gt;
*[[Moodle-specific customisations to the HTML editor]]&lt;br /&gt;
*[[Moodle Automatic Regression Test and Inspection Nit-picker]]&lt;br /&gt;
*[[ VSTU projects|Projects developed in Volgograd State Technical University]] becomes to many to simple list them on that page.&lt;br /&gt;
*[[HTML5_player|HTML5 player]]&lt;br /&gt;
&lt;br /&gt;
== Markup &amp;amp; Theming ==&lt;br /&gt;
* [[Moodle CSS System]], idea from forum discussion on [http://moodle.org/mod/forum/discuss.php?d=126009 Object Oriented CSS]&lt;br /&gt;
&lt;br /&gt;
==Other==&lt;br /&gt;
&lt;br /&gt;
*[[MoodleDocs development]]&lt;br /&gt;
*[[Usability]]&lt;br /&gt;
*[[Document Management API]]&lt;br /&gt;
*[[wikindx|Possible integration of WIKINDX with Moodle]]&lt;br /&gt;
*[[Snapshot - flat HTML export of complete course]]&lt;br /&gt;
*[[Offline Moodle | Development:Offline Moodle - A Moodle that runs on a mobile device with the internet]]&lt;br /&gt;
*[[A standard set of fixtures for unit tests?|A standard set of fixtures for unit tests?]]&lt;br /&gt;
*[[reportbuilder|Possible integration Totara Report Builder into Moodle]]&lt;br /&gt;
*[[openbadges|Open Badges]]&lt;br /&gt;
*[[Course Reset Proposal]]&lt;br /&gt;
&lt;br /&gt;
==Archive: past proposals==&lt;br /&gt;
&lt;br /&gt;
===Things that got implemented===&lt;br /&gt;
&lt;br /&gt;
====Core code====&lt;br /&gt;
&lt;br /&gt;
*[[Ajax user selector|Ajax user selector]]&lt;br /&gt;
*[[Roles]] - in Moodle 1.7&lt;br /&gt;
*[[Moodle forms library]] - in Moodle 1.8&lt;br /&gt;
**[[Martin form notes]]&lt;br /&gt;
&lt;br /&gt;
====Quiz &amp;amp; question types====&lt;br /&gt;
&lt;br /&gt;
*[[Quiz UI redesign | Quiz UI redesign]]&lt;br /&gt;
*[[Administration page for question types|Administration page for question types]]&lt;br /&gt;
*[[Plan_to_Improve_Flexibility_of_Question_Category_Sharing_and_Permissions|Plans for enhancing the question bank]] - in Moodle 1.9&lt;br /&gt;
*[[Email notification when a quiz is submitted|Email notification when a quiz is submitted]] - in Moodle 1.9&lt;br /&gt;
*[[Plans for enhancing import/export in questiontype plugins]] - in Moodle 1.9&lt;br /&gt;
*[[quiz_navigation | Quiz navigation]]&lt;br /&gt;
*[[Open_protocol_for_accessing_question_engines|Open protocol for accessing question engines]]&lt;br /&gt;
*[[Quiz report enhancements|Quiz report enhancements]]&lt;br /&gt;
*[[Flagging questions during a quiz attempt|Flagging questions during a quiz attempt]]&lt;br /&gt;
&lt;br /&gt;
====Other====&lt;br /&gt;
&lt;br /&gt;
*[[Quiz and quesions community testing day]]&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Developer_notes&amp;diff=54098</id>
		<title>Developer notes</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Developer_notes&amp;diff=54098"/>
		<updated>2018-05-01T10:47:59Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: /* Other */ Add html5 player orphaned page.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This area is for developers to work on various bits of code and documentation as necessary. Once material has matured it should be linked to from the main [[Developer documentation|Developer documentation]] page.&lt;br /&gt;
&lt;br /&gt;
==Core code==&lt;br /&gt;
&lt;br /&gt;
*[[Other lang issues|Language issues]] &lt;br /&gt;
*[[Datalib Notes]]&lt;br /&gt;
*[[Application/session variables]]&lt;br /&gt;
*[[Filters schema]]&lt;br /&gt;
*[[Filterall support]]&lt;br /&gt;
*[[Groups documentation for module developers]]&lt;br /&gt;
*[[Plan to improve ability to delegate administrator tasks to course category level|Plan to improve ability to delegate administrator tasks to course category level]]&lt;br /&gt;
*[[Stealth mode and nested activities|Stealth mode and nested activities]]&lt;br /&gt;
*[[Enrolment_plugins_2.0|How enrolments should work in Moodle 2.0]]&lt;br /&gt;
*[[Redesigning the override roles page|Redesigning the override roles page]]&lt;br /&gt;
&lt;br /&gt;
===Gradebook===&lt;br /&gt;
&lt;br /&gt;
*[[Gradebook_improvements|Gradebook improvements]] - ideas from Petr.&lt;br /&gt;
*[[Tim&#039;s_Gradebook_thoughts|Tim&#039;s Gradebook thoughts]]&lt;br /&gt;
&lt;br /&gt;
==Modules and other recognised plugin types==&lt;br /&gt;
&lt;br /&gt;
===Lesson===&lt;br /&gt;
&lt;br /&gt;
*[[Adding_question_types_to_lesson|Adding question types to lesson module]]&lt;br /&gt;
*[[New lesson navigation | New lesson navigation]]&lt;br /&gt;
*[[Adding blocks to lesson | Adding blocks to lesson]]&lt;br /&gt;
&lt;br /&gt;
===Quiz &amp;amp; question types===&lt;br /&gt;
&lt;br /&gt;
* [[File storage conversion Quiz and Questions|File storage conversion Quiz and Questions]] - notes for MDL-16094.&lt;br /&gt;
* [[How the quiz navigation should work in Moodle 2.0|How the quiz navigation should work in Moodle 2.0]] - MDL-20276.&lt;br /&gt;
* [[Moodle 2.0 question bank improvements|Moodle 2.0 question bank improvements]] - including question tagging and improved searchability.&lt;br /&gt;
* [[Question_Engine_2|Proposal to change the Moodle Question Engine]] This supersedes &lt;br /&gt;
** [[Plans for adaptive mode|Plans for adaptive mode]]&lt;br /&gt;
** [[Implementation of true negative marks in MC-type questions|Implementation of true negative marks in MC-type questions]]&lt;br /&gt;
* [[Calculated question : adding new math functions]]&lt;br /&gt;
* [[Numerical question units and intervals]]&lt;br /&gt;
* [[Future question bank/sharing/versioning requirements|Future question bank/sharing/versioning requirements]]&lt;br /&gt;
* [[States of a quiz attempt]]&lt;br /&gt;
* [[Optional checkbox &amp;quot;This is all my own work&amp;quot; before submitting a quiz]]&lt;br /&gt;
* [[The OU PMatch algorithm]]&lt;br /&gt;
* [[Provide print option for a Quiz]]&lt;br /&gt;
&lt;br /&gt;
===Other activity modules===&lt;br /&gt;
&lt;br /&gt;
*[[Forum development|Forum functional upgrade]]&lt;br /&gt;
*[[Wiki development|Wiki module development]]&lt;br /&gt;
*[[Schedule development|Proposed replacement for Scheduler]]&lt;br /&gt;
&lt;br /&gt;
===Gradebook Plugins===&lt;br /&gt;
&lt;br /&gt;
*[[External Database Plugin]]&lt;br /&gt;
&lt;br /&gt;
===Other===&lt;br /&gt;
&lt;br /&gt;
*[[Blogs and forums|Blogs, forums and the nature of discussion]]&lt;br /&gt;
*[[Conditional activities]]&lt;br /&gt;
*[[Improved Payment Plugin]]&lt;br /&gt;
*[[Moodle-specific customisations to the HTML editor]]&lt;br /&gt;
*[[Moodle Automatic Regression Test and Inspection Nit-picker]]&lt;br /&gt;
*[[ VSTU projects|Projects developed in Volgograd State Technical University]] becomes to many to simple list them on that page.&lt;br /&gt;
*[[HTML5 player|HTML5_player]]&lt;br /&gt;
&lt;br /&gt;
== Markup &amp;amp; Theming ==&lt;br /&gt;
* [[Moodle CSS System]], idea from forum discussion on [http://moodle.org/mod/forum/discuss.php?d=126009 Object Oriented CSS]&lt;br /&gt;
&lt;br /&gt;
==Other==&lt;br /&gt;
&lt;br /&gt;
*[[MoodleDocs development]]&lt;br /&gt;
*[[Usability]]&lt;br /&gt;
*[[Document Management API]]&lt;br /&gt;
*[[wikindx|Possible integration of WIKINDX with Moodle]]&lt;br /&gt;
*[[Snapshot - flat HTML export of complete course]]&lt;br /&gt;
*[[Offline Moodle | Development:Offline Moodle - A Moodle that runs on a mobile device with the internet]]&lt;br /&gt;
*[[A standard set of fixtures for unit tests?|A standard set of fixtures for unit tests?]]&lt;br /&gt;
*[[reportbuilder|Possible integration Totara Report Builder into Moodle]]&lt;br /&gt;
*[[openbadges|Open Badges]]&lt;br /&gt;
*[[Course Reset Proposal]]&lt;br /&gt;
&lt;br /&gt;
==Archive: past proposals==&lt;br /&gt;
&lt;br /&gt;
===Things that got implemented===&lt;br /&gt;
&lt;br /&gt;
====Core code====&lt;br /&gt;
&lt;br /&gt;
*[[Ajax user selector|Ajax user selector]]&lt;br /&gt;
*[[Roles]] - in Moodle 1.7&lt;br /&gt;
*[[Moodle forms library]] - in Moodle 1.8&lt;br /&gt;
**[[Martin form notes]]&lt;br /&gt;
&lt;br /&gt;
====Quiz &amp;amp; question types====&lt;br /&gt;
&lt;br /&gt;
*[[Quiz UI redesign | Quiz UI redesign]]&lt;br /&gt;
*[[Administration page for question types|Administration page for question types]]&lt;br /&gt;
*[[Plan_to_Improve_Flexibility_of_Question_Category_Sharing_and_Permissions|Plans for enhancing the question bank]] - in Moodle 1.9&lt;br /&gt;
*[[Email notification when a quiz is submitted|Email notification when a quiz is submitted]] - in Moodle 1.9&lt;br /&gt;
*[[Plans for enhancing import/export in questiontype plugins]] - in Moodle 1.9&lt;br /&gt;
*[[quiz_navigation | Quiz navigation]]&lt;br /&gt;
*[[Open_protocol_for_accessing_question_engines|Open protocol for accessing question engines]]&lt;br /&gt;
*[[Quiz report enhancements|Quiz report enhancements]]&lt;br /&gt;
*[[Flagging questions during a quiz attempt|Flagging questions during a quiz attempt]]&lt;br /&gt;
&lt;br /&gt;
====Other====&lt;br /&gt;
&lt;br /&gt;
*[[Quiz and quesions community testing day]]&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=54097</id>
		<title>HTML5 player</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=54097"/>
		<updated>2018-05-01T10:46:32Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}&lt;br /&gt;
{{Infobox Project&lt;br /&gt;
|name = HTML5 Player with flash fallback&lt;br /&gt;
|state = Closed, released in 3.2&lt;br /&gt;
|tracker = https://tracker.moodle.org/browse/MDL-38158&lt;br /&gt;
|discussion = https://moodle.org/mod/forum/discuss.php?d=222753#p1110024&lt;br /&gt;
|assignee = [https://tracker.moodle.org/secure/ViewProfile.jspa?name=marina Marina Glancy]&lt;br /&gt;
}}&lt;br /&gt;
{{Moodle 2.x}}&lt;br /&gt;
&lt;br /&gt;
== Project goals ==&lt;br /&gt;
&lt;br /&gt;
The purpose of this document is to choose HTML5 player with flash fallback for integration in Moodle and plan its implementation.&lt;br /&gt;
&lt;br /&gt;
The aim of this change is to reach a consistent look of the player among different platforms and browsers, as well as making sure that player starts using flash if html5 is not supported by browser for the given format. Another aim is to improve accessibility and usability, enhance customisation.&lt;br /&gt;
&lt;br /&gt;
== Considerations ==&lt;br /&gt;
&lt;br /&gt;
* Usability of the player - is it easy to use it and intuitively understand how to use controls?&lt;br /&gt;
* Accessibility of the player - possibility of keyboard navigation, subtitles, support?&lt;br /&gt;
* Appearance of the player - can its interface be modified, themes support, RTL?&lt;br /&gt;
* Consistency among browsers - does player look the same?&lt;br /&gt;
* Audio support - can player handle HTML5 &amp;lt;audio&amp;gt; tag?&lt;br /&gt;
* Mobile platforms support - does player also work on iOS and Android?&lt;br /&gt;
* Streaming media support (including adaptive-bitrate delivery) - can player handle RTMP, Apple HLS, Adobe HDS, Microsoft HSS?&lt;br /&gt;
* Plugins support - can we use or develop community plugins easily?&lt;br /&gt;
* Embedding support - so users could post media content outside Moodle, if permitted.&lt;br /&gt;
* Maintainability of the links between the player and Moodle - how much work will we need to do every time we upgrade?&lt;br /&gt;
&lt;br /&gt;
== Candidates ==&lt;br /&gt;
&lt;br /&gt;
* [http://flowplayer.org/ Flowplayer HTML5]&lt;br /&gt;
* [http://www.videojs.com/ Video.JS]&lt;br /&gt;
* [http://www.projekktor.com/ Projekktor]&lt;br /&gt;
* [http://mediaelementjs.com/ MediaElement.js]&lt;br /&gt;
* ?Are there other alternatives?&lt;br /&gt;
&lt;br /&gt;
== Comparison Matrix ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! [[#Flowplayer_HTML5|Flowplayer HTML5]]&lt;br /&gt;
! [[#Video.JS|Video.JS]]&lt;br /&gt;
! [[#Projekktor|Projekktor]]&lt;br /&gt;
! [[#MediaElement.js|MediaElement.js]]&lt;br /&gt;
! No Player&lt;br /&gt;
|-&lt;br /&gt;
! Accessible Player:&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Keyboard control&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (http://accessibility.oit.ncsu.edu/blog/2013/05/09/accessible-video-js-player-available-on-global-accessibility-awareness-day/) This was instructed by Greg Krause, one of the key accessibility advisors for Moodle.&lt;br /&gt;
| Yes (configurable)&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Subtitles support&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via plugin)&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (see http://caniuse.com/webvtt)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Touch interface&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Appearance:&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Skins&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* CSS customisation&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTL support&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| No&lt;br /&gt;
| Unknown (CSS, so I guess so...)&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Mobile platforms:&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* iOS&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Android&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Streaming protocols:&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTMP&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via playlist)&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Adaptive HTTP&lt;br /&gt;
| HLS&lt;br /&gt;
| HLS (via plugin)&lt;br /&gt;
| HLS (via playlist)&lt;br /&gt;
| HLS&lt;br /&gt;
| via Media Source Extension&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* MPEG-DASH&lt;br /&gt;
| Yes (via [http://demos.flowplayer.org/api/dash.html plugin])&lt;br /&gt;
| Yes (via [https://github.com/videojs/videojs-contrib-dash plugin])&lt;br /&gt;
| ?&lt;br /&gt;
| ?&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
! Audio player&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Embedding support&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (configurable)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via addThis plugin)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via plugin)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | No&lt;br /&gt;
|-&lt;br /&gt;
! License&lt;br /&gt;
| GPL v3 (with additional terms)&lt;br /&gt;
| Apache 2&lt;br /&gt;
| GPL v3&lt;br /&gt;
| MIT&lt;br /&gt;
| no extra code needed&lt;br /&gt;
|-&lt;br /&gt;
! JS library&lt;br /&gt;
| jQuery&lt;br /&gt;
| -&lt;br /&gt;
| jQuery&lt;br /&gt;
| jQuery&lt;br /&gt;
| none required&lt;br /&gt;
|-&lt;br /&gt;
! Plugins infrastructure&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
! Flash fallback player&lt;br /&gt;
| Flowplayer Flash&lt;br /&gt;
| video-js flash&lt;br /&gt;
| StobeMediaPlayback (but can be jarisplayer or some other).&lt;br /&gt;
| Flash and Silverlight (for .wmv support) fallback, used to provide the HTML5 video/audio elements.&lt;br /&gt;
| The Video tag can contain fallback content (e.g. Flash object) for browsers that don&#039;t support it at all (http://camendesign.com/code/video_for_everybody), but not based on codec support.&lt;br /&gt;
|-&lt;br /&gt;
! API&lt;br /&gt;
| Yes (plus window.flowplayer object)&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Flowplayer HTML5 ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* Good looking player, resembles existing flash flowplayer in Moodle (with &amp;quot;functional&amp;quot; skin)&lt;br /&gt;
* Extensive customisation (via CSS3 skins and configuration object)&lt;br /&gt;
* Streaming support (RTMP, HLS)&lt;br /&gt;
* Good accessibility features&lt;br /&gt;
* Configurable embedding functionality&lt;br /&gt;
* Existing flash flowplayer can be configured for fallback (the appearance of player will not be affected).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Require jQuery for functioning&lt;br /&gt;
* Flowplayer logo remains on screen&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using wrapper around &amp;lt;video&amp;gt;.&lt;br /&gt;
* width and height attributes in video tag are ignored, player size is configured via wrapper size only.&lt;br /&gt;
* RTMP server connection is configured via data-rtmp attribute in wrapper or player init config parameter, actual path the file specified in src attribute of source item.&lt;br /&gt;
* &amp;lt;source type=&amp;quot;video/flash&amp;quot;... dummy MIME type to force using plash player for whatever content.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Plugins infrastructure&lt;br /&gt;
* No audio support&lt;br /&gt;
&lt;br /&gt;
=== Video.JS ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Extensive API.&lt;br /&gt;
* No extra JS library needed.&lt;br /&gt;
* Many plugins.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Poor documentation&lt;br /&gt;
* RTMP requires non-standard MIME.&lt;br /&gt;
* Android and iOS override Video.JS with own player, when not overridden, content is not playing.&lt;br /&gt;
* No RTL.&lt;br /&gt;
* HLS support via plugin (many files to include, external contributor see https://github.com/videojs/videojs-contrib-hls).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* RTMP server connection and path specified as single URI in src attribute of source item, &#039;&amp;amp;&#039; character is used as server connection and path divider.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Embedded HLS support.&lt;br /&gt;
&lt;br /&gt;
=== MediaElement.js ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* Flash fall-forward - uses Flash/Silverlight to provide the HTML5 MediaElement API.&lt;br /&gt;
* Consistent HTML/CSS Player&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* ...&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* ...&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* ...&lt;br /&gt;
&lt;br /&gt;
=== Projekktor ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Well documented API.&lt;br /&gt;
* Media RSS support.&lt;br /&gt;
* Possibility to choose flash player for fallback (included by default are StrobeMediaPlayback and Jarisplayer, both Open Source).&lt;br /&gt;
* Platform preference order selection (e.g. browser, ios, android, flash, native).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Uses flash where it is not supposed to (e.g. mp4 in Chrome).&lt;br /&gt;
* Issues on ios and android (suggests to download file when play button is pressed).&lt;br /&gt;
* RTMP only work if defined via playlist rather than in &amp;lt;source&amp;gt; tags.&lt;br /&gt;
* Subtitles plugin is not free.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* Make sure &amp;lt;video&amp;gt; tag has class attribute with &#039;projekktor&#039; value (even if you initialise it by ID of the element), player will not work properly otherwise.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== HTML5 browser native ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* Simple&lt;br /&gt;
* Standard on mobile&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* IE8 has no support&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes&#039;&#039;&#039;&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Cross-browser support ==&lt;br /&gt;
&lt;br /&gt;
=== Method ===&lt;br /&gt;
Compatibility checks were done manually by accessing the sample page using different browsers and platforms. Sample page contained the list of identical player instances, initialised for each &amp;lt;video&amp;gt; definition with a &amp;lt;source&amp;gt; of particular format: mp4, webm, ogg, flv. Streaming support was checked by setting up a &amp;lt;video&amp;gt; container with two sources of the same video, one was HLS (Apple HTTP Live Streaming) stream for browsers and platforms that support html5 video streaming, another one was RTMP which is played using flash engine and supposed to be used in case if HLS is not supported.&lt;br /&gt;
&lt;br /&gt;
=== Sample Pages ===&lt;br /&gt;
&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=flowplayer Flowplayer HTML5] version 5.4.6.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=videojs Video.JS] version 4.4.1.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=projekktor Projekktor] version 1.3.09.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=mediaelementjs MediaElement.js] version 2.6.14&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=native Native browser support].&lt;br /&gt;
&lt;br /&gt;
=== Source ===&lt;br /&gt;
&lt;br /&gt;
Source of testing page is hosted on [https://github.com/kabalin/test-html5-players/blob/master/players.php github]. The actual source of the html page can be viewed in browser.&lt;br /&gt;
&lt;br /&gt;
=== Discussion ===&lt;br /&gt;
&lt;br /&gt;
The players comparison that has been carried out demonstrated that &amp;quot;least hassle&amp;quot; player is Flowplayer. Despite some drawbacks listed in [[#Flowplayer_HTML5|corresponding section above]], it is clearly a winner as it works as expected and according to documentation for all browsers and platforms I had chance to test it. This is the only player that supports RTL layout, display platform incompatibility message prior to attempt to play, and was simple to configure (no undocumented tricks that I had to figure out to make it work). Both VideoJS and Projekktor do now perform properly in all cases. Among those two, I personally prefer Projekktor more for its extensive API, plugins infrastructure and configuration flexibility. However problems on mobile platforms and flash fallback inconsistency make them unreliable at this stage.&lt;br /&gt;
&lt;br /&gt;
=== Compatibility results ===&lt;br /&gt;
&lt;br /&gt;
The table was populated using Flowplayer as others do not perform good enough with some formats and platforms, e.g. VideoJS allow mobile platform player to override itself, Projekktor does not always use HTML5 where browser clearly can handle it (supported in native mode and Flowplayer).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Browser&lt;br /&gt;
! mp4&lt;br /&gt;
! webm&lt;br /&gt;
! ogg&lt;br /&gt;
! flv&lt;br /&gt;
! RTMP/HLS*&lt;br /&gt;
|-&lt;br /&gt;
! Windows 7&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Firefox 27.0.1&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 12.16&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 5.1.7&lt;br /&gt;
| flash&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Internet Explorer 11.0.9600.x&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Linux (Debian Wheezy)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.115&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! OSX 10.9&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 7.0 (9537.71)&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 phone (CyanogenMod, no flash)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 tablet (GalaxyTab2, flash app 11.1.115.36)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 19.0.1340.x&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
! iPhone 4S (6.1.3)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! iPad 4 (7.0.6)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;small&amp;gt;* For HLS/RTMP, html5 in the table means HLS has been used, flash means player fell back and used RTMP.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sub Tasks ==&lt;br /&gt;
&lt;br /&gt;
In initial stage FlowPlayer HTML5 (or any other) will handle all existing HTML5 Video extensions as per core_media_player_html5video class, plus m3u8 (HLS). It will also be possible optionally to make flash files handled by HTML5 Video player as well (possibility of using existing flash FlowPlayer for flv files will remain).&lt;br /&gt;
&lt;br /&gt;
== Mock-Ups/Prototypes ==&lt;br /&gt;
&lt;br /&gt;
See [[#Sample_Pages|Sample pages]] section.&lt;br /&gt;
&lt;br /&gt;
== Workaround ==&lt;br /&gt;
&lt;br /&gt;
As intermediate solution, if you require player consistency throughout all browsers and platforms, you may consider using JW Player filter: https://github.com/lucisgit/moodle-filter_jwplayer Notice, that JW Player is not free for commercial use.&lt;br /&gt;
&lt;br /&gt;
== Related Tracker Issues ==&lt;br /&gt;
* MDL-38158&lt;br /&gt;
&lt;br /&gt;
== Useful links ==&lt;br /&gt;
* http://praegnanz.de/html5video/&lt;br /&gt;
* http://html5video.org/wiki/HTML5_Video_Player_Comparison&lt;br /&gt;
* http://www.streamingmedia.com/Articles/Editorial/Featured-Articles/Choosing-a-Video-Player-Features-and-Specs-for-the-Top-Five-94188.aspx&lt;br /&gt;
* A mind map representation of [https://www.mindmup.com/#m:g10BzEUW_tmkNcvVFZ5d1N4VUV5UUU using Video in various parts and plugins of Moodle]. &lt;br /&gt;
&lt;br /&gt;
[[Category:Project]]&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=54096</id>
		<title>HTML5 player</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=54096"/>
		<updated>2018-05-01T10:45:58Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}&lt;br /&gt;
{{Infobox Project&lt;br /&gt;
|name = HTML5 Player with flash fallback&lt;br /&gt;
|state = Closed, released in 3.2&lt;br /&gt;
|tracker = https://tracker.moodle.org/browse/MDL-38158&lt;br /&gt;
|discussion = https://moodle.org/mod/forum/discuss.php?d=222753#p1110024&lt;br /&gt;
|assignee = [https://tracker.moodle.org/secure/ViewProfile.jspa?name=marina Ruslan Kabalin]&lt;br /&gt;
}}&lt;br /&gt;
{{Moodle 2.x}}&lt;br /&gt;
&lt;br /&gt;
== Project goals ==&lt;br /&gt;
&lt;br /&gt;
The purpose of this document is to choose HTML5 player with flash fallback for integration in Moodle and plan its implementation.&lt;br /&gt;
&lt;br /&gt;
The aim of this change is to reach a consistent look of the player among different platforms and browsers, as well as making sure that player starts using flash if html5 is not supported by browser for the given format. Another aim is to improve accessibility and usability, enhance customisation.&lt;br /&gt;
&lt;br /&gt;
== Considerations ==&lt;br /&gt;
&lt;br /&gt;
* Usability of the player - is it easy to use it and intuitively understand how to use controls?&lt;br /&gt;
* Accessibility of the player - possibility of keyboard navigation, subtitles, support?&lt;br /&gt;
* Appearance of the player - can its interface be modified, themes support, RTL?&lt;br /&gt;
* Consistency among browsers - does player look the same?&lt;br /&gt;
* Audio support - can player handle HTML5 &amp;lt;audio&amp;gt; tag?&lt;br /&gt;
* Mobile platforms support - does player also work on iOS and Android?&lt;br /&gt;
* Streaming media support (including adaptive-bitrate delivery) - can player handle RTMP, Apple HLS, Adobe HDS, Microsoft HSS?&lt;br /&gt;
* Plugins support - can we use or develop community plugins easily?&lt;br /&gt;
* Embedding support - so users could post media content outside Moodle, if permitted.&lt;br /&gt;
* Maintainability of the links between the player and Moodle - how much work will we need to do every time we upgrade?&lt;br /&gt;
&lt;br /&gt;
== Candidates ==&lt;br /&gt;
&lt;br /&gt;
* [http://flowplayer.org/ Flowplayer HTML5]&lt;br /&gt;
* [http://www.videojs.com/ Video.JS]&lt;br /&gt;
* [http://www.projekktor.com/ Projekktor]&lt;br /&gt;
* [http://mediaelementjs.com/ MediaElement.js]&lt;br /&gt;
* ?Are there other alternatives?&lt;br /&gt;
&lt;br /&gt;
== Comparison Matrix ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! [[#Flowplayer_HTML5|Flowplayer HTML5]]&lt;br /&gt;
! [[#Video.JS|Video.JS]]&lt;br /&gt;
! [[#Projekktor|Projekktor]]&lt;br /&gt;
! [[#MediaElement.js|MediaElement.js]]&lt;br /&gt;
! No Player&lt;br /&gt;
|-&lt;br /&gt;
! Accessible Player:&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Keyboard control&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (http://accessibility.oit.ncsu.edu/blog/2013/05/09/accessible-video-js-player-available-on-global-accessibility-awareness-day/) This was instructed by Greg Krause, one of the key accessibility advisors for Moodle.&lt;br /&gt;
| Yes (configurable)&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Subtitles support&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via plugin)&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (see http://caniuse.com/webvtt)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Touch interface&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Appearance:&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Skins&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* CSS customisation&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTL support&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| No&lt;br /&gt;
| Unknown (CSS, so I guess so...)&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Mobile platforms:&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* iOS&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Android&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Streaming protocols:&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTMP&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via playlist)&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Adaptive HTTP&lt;br /&gt;
| HLS&lt;br /&gt;
| HLS (via plugin)&lt;br /&gt;
| HLS (via playlist)&lt;br /&gt;
| HLS&lt;br /&gt;
| via Media Source Extension&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* MPEG-DASH&lt;br /&gt;
| Yes (via [http://demos.flowplayer.org/api/dash.html plugin])&lt;br /&gt;
| Yes (via [https://github.com/videojs/videojs-contrib-dash plugin])&lt;br /&gt;
| ?&lt;br /&gt;
| ?&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
! Audio player&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Embedding support&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (configurable)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via addThis plugin)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via plugin)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | No&lt;br /&gt;
|-&lt;br /&gt;
! License&lt;br /&gt;
| GPL v3 (with additional terms)&lt;br /&gt;
| Apache 2&lt;br /&gt;
| GPL v3&lt;br /&gt;
| MIT&lt;br /&gt;
| no extra code needed&lt;br /&gt;
|-&lt;br /&gt;
! JS library&lt;br /&gt;
| jQuery&lt;br /&gt;
| -&lt;br /&gt;
| jQuery&lt;br /&gt;
| jQuery&lt;br /&gt;
| none required&lt;br /&gt;
|-&lt;br /&gt;
! Plugins infrastructure&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
! Flash fallback player&lt;br /&gt;
| Flowplayer Flash&lt;br /&gt;
| video-js flash&lt;br /&gt;
| StobeMediaPlayback (but can be jarisplayer or some other).&lt;br /&gt;
| Flash and Silverlight (for .wmv support) fallback, used to provide the HTML5 video/audio elements.&lt;br /&gt;
| The Video tag can contain fallback content (e.g. Flash object) for browsers that don&#039;t support it at all (http://camendesign.com/code/video_for_everybody), but not based on codec support.&lt;br /&gt;
|-&lt;br /&gt;
! API&lt;br /&gt;
| Yes (plus window.flowplayer object)&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Flowplayer HTML5 ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* Good looking player, resembles existing flash flowplayer in Moodle (with &amp;quot;functional&amp;quot; skin)&lt;br /&gt;
* Extensive customisation (via CSS3 skins and configuration object)&lt;br /&gt;
* Streaming support (RTMP, HLS)&lt;br /&gt;
* Good accessibility features&lt;br /&gt;
* Configurable embedding functionality&lt;br /&gt;
* Existing flash flowplayer can be configured for fallback (the appearance of player will not be affected).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Require jQuery for functioning&lt;br /&gt;
* Flowplayer logo remains on screen&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using wrapper around &amp;lt;video&amp;gt;.&lt;br /&gt;
* width and height attributes in video tag are ignored, player size is configured via wrapper size only.&lt;br /&gt;
* RTMP server connection is configured via data-rtmp attribute in wrapper or player init config parameter, actual path the file specified in src attribute of source item.&lt;br /&gt;
* &amp;lt;source type=&amp;quot;video/flash&amp;quot;... dummy MIME type to force using plash player for whatever content.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Plugins infrastructure&lt;br /&gt;
* No audio support&lt;br /&gt;
&lt;br /&gt;
=== Video.JS ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Extensive API.&lt;br /&gt;
* No extra JS library needed.&lt;br /&gt;
* Many plugins.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Poor documentation&lt;br /&gt;
* RTMP requires non-standard MIME.&lt;br /&gt;
* Android and iOS override Video.JS with own player, when not overridden, content is not playing.&lt;br /&gt;
* No RTL.&lt;br /&gt;
* HLS support via plugin (many files to include, external contributor see https://github.com/videojs/videojs-contrib-hls).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* RTMP server connection and path specified as single URI in src attribute of source item, &#039;&amp;amp;&#039; character is used as server connection and path divider.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Embedded HLS support.&lt;br /&gt;
&lt;br /&gt;
=== MediaElement.js ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* Flash fall-forward - uses Flash/Silverlight to provide the HTML5 MediaElement API.&lt;br /&gt;
* Consistent HTML/CSS Player&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* ...&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* ...&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* ...&lt;br /&gt;
&lt;br /&gt;
=== Projekktor ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Well documented API.&lt;br /&gt;
* Media RSS support.&lt;br /&gt;
* Possibility to choose flash player for fallback (included by default are StrobeMediaPlayback and Jarisplayer, both Open Source).&lt;br /&gt;
* Platform preference order selection (e.g. browser, ios, android, flash, native).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Uses flash where it is not supposed to (e.g. mp4 in Chrome).&lt;br /&gt;
* Issues on ios and android (suggests to download file when play button is pressed).&lt;br /&gt;
* RTMP only work if defined via playlist rather than in &amp;lt;source&amp;gt; tags.&lt;br /&gt;
* Subtitles plugin is not free.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* Make sure &amp;lt;video&amp;gt; tag has class attribute with &#039;projekktor&#039; value (even if you initialise it by ID of the element), player will not work properly otherwise.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== HTML5 browser native ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* Simple&lt;br /&gt;
* Standard on mobile&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* IE8 has no support&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes&#039;&#039;&#039;&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Cross-browser support ==&lt;br /&gt;
&lt;br /&gt;
=== Method ===&lt;br /&gt;
Compatibility checks were done manually by accessing the sample page using different browsers and platforms. Sample page contained the list of identical player instances, initialised for each &amp;lt;video&amp;gt; definition with a &amp;lt;source&amp;gt; of particular format: mp4, webm, ogg, flv. Streaming support was checked by setting up a &amp;lt;video&amp;gt; container with two sources of the same video, one was HLS (Apple HTTP Live Streaming) stream for browsers and platforms that support html5 video streaming, another one was RTMP which is played using flash engine and supposed to be used in case if HLS is not supported.&lt;br /&gt;
&lt;br /&gt;
=== Sample Pages ===&lt;br /&gt;
&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=flowplayer Flowplayer HTML5] version 5.4.6.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=videojs Video.JS] version 4.4.1.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=projekktor Projekktor] version 1.3.09.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=mediaelementjs MediaElement.js] version 2.6.14&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=native Native browser support].&lt;br /&gt;
&lt;br /&gt;
=== Source ===&lt;br /&gt;
&lt;br /&gt;
Source of testing page is hosted on [https://github.com/kabalin/test-html5-players/blob/master/players.php github]. The actual source of the html page can be viewed in browser.&lt;br /&gt;
&lt;br /&gt;
=== Discussion ===&lt;br /&gt;
&lt;br /&gt;
The players comparison that has been carried out demonstrated that &amp;quot;least hassle&amp;quot; player is Flowplayer. Despite some drawbacks listed in [[#Flowplayer_HTML5|corresponding section above]], it is clearly a winner as it works as expected and according to documentation for all browsers and platforms I had chance to test it. This is the only player that supports RTL layout, display platform incompatibility message prior to attempt to play, and was simple to configure (no undocumented tricks that I had to figure out to make it work). Both VideoJS and Projekktor do now perform properly in all cases. Among those two, I personally prefer Projekktor more for its extensive API, plugins infrastructure and configuration flexibility. However problems on mobile platforms and flash fallback inconsistency make them unreliable at this stage.&lt;br /&gt;
&lt;br /&gt;
=== Compatibility results ===&lt;br /&gt;
&lt;br /&gt;
The table was populated using Flowplayer as others do not perform good enough with some formats and platforms, e.g. VideoJS allow mobile platform player to override itself, Projekktor does not always use HTML5 where browser clearly can handle it (supported in native mode and Flowplayer).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Browser&lt;br /&gt;
! mp4&lt;br /&gt;
! webm&lt;br /&gt;
! ogg&lt;br /&gt;
! flv&lt;br /&gt;
! RTMP/HLS*&lt;br /&gt;
|-&lt;br /&gt;
! Windows 7&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Firefox 27.0.1&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 12.16&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 5.1.7&lt;br /&gt;
| flash&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Internet Explorer 11.0.9600.x&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Linux (Debian Wheezy)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.115&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! OSX 10.9&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 7.0 (9537.71)&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 phone (CyanogenMod, no flash)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 tablet (GalaxyTab2, flash app 11.1.115.36)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 19.0.1340.x&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
! iPhone 4S (6.1.3)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! iPad 4 (7.0.6)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;small&amp;gt;* For HLS/RTMP, html5 in the table means HLS has been used, flash means player fell back and used RTMP.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sub Tasks ==&lt;br /&gt;
&lt;br /&gt;
In initial stage FlowPlayer HTML5 (or any other) will handle all existing HTML5 Video extensions as per core_media_player_html5video class, plus m3u8 (HLS). It will also be possible optionally to make flash files handled by HTML5 Video player as well (possibility of using existing flash FlowPlayer for flv files will remain).&lt;br /&gt;
&lt;br /&gt;
== Mock-Ups/Prototypes ==&lt;br /&gt;
&lt;br /&gt;
See [[#Sample_Pages|Sample pages]] section.&lt;br /&gt;
&lt;br /&gt;
== Workaround ==&lt;br /&gt;
&lt;br /&gt;
As intermediate solution, if you require player consistency throughout all browsers and platforms, you may consider using JW Player filter: https://github.com/lucisgit/moodle-filter_jwplayer Notice, that JW Player is not free for commercial use.&lt;br /&gt;
&lt;br /&gt;
== Related Tracker Issues ==&lt;br /&gt;
* MDL-38158&lt;br /&gt;
&lt;br /&gt;
== Useful links ==&lt;br /&gt;
* http://praegnanz.de/html5video/&lt;br /&gt;
* http://html5video.org/wiki/HTML5_Video_Player_Comparison&lt;br /&gt;
* http://www.streamingmedia.com/Articles/Editorial/Featured-Articles/Choosing-a-Video-Player-Features-and-Specs-for-the-Top-Five-94188.aspx&lt;br /&gt;
* A mind map representation of [https://www.mindmup.com/#m:g10BzEUW_tmkNcvVFZ5d1N4VUV5UUU using Video in various parts and plugins of Moodle]. &lt;br /&gt;
&lt;br /&gt;
[[Category:Project]]&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Frankenstyle&amp;diff=50259</id>
		<title>Frankenstyle</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Frankenstyle&amp;diff=50259"/>
		<updated>2016-05-23T15:46:46Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: /* Core subsystems */ Add antivirus&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;Frankenstyle component names&#039; refers to the naming convention that is used to uniquely identify a Moodle plugin based on the type of plugin and its name.  They are used throughout the Moodle code (with a notable exception being the css class names in the themes).&lt;br /&gt;
&lt;br /&gt;
Martin Dougiamas invented the word &#039;frankenstyle&#039; to describe this naming system which was invented by Petr Škoda.&lt;br /&gt;
&lt;br /&gt;
== Format ==&lt;br /&gt;
&lt;br /&gt;
Frankenstyle component names have a prefix and then a folder name, separated by an underscore. &lt;br /&gt;
&lt;br /&gt;
# The prefix is determined by the type of plugin. For example, the prefix for an activity module is &#039;&#039;&#039;mod&#039;&#039;&#039;.&lt;br /&gt;
# The name is the folder name of the plugin, always lower case.  For example, the name for Quiz is &#039;&#039;&#039;quiz&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
So the frankenstyle component name for the quiz module is &#039;&#039;&#039;mod_quiz&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Plugin types ==&lt;br /&gt;
&lt;br /&gt;
See [[Plugin types]] page for the list of all supported plugin types in Moodle and their frankenstyle prefix.&lt;br /&gt;
&lt;br /&gt;
To get a definitive list in your version of Moodle 2.x, use a small Moodle script with &amp;lt;tt&amp;gt;print_object(get_plugin_types());&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Core subsystems ==&lt;br /&gt;
&lt;br /&gt;
Subsystems in Moodle are not plugins themselves but can be referred to using &#039;&#039;&#039;core_xxx&#039;&#039;&#039; where xxx is the subsystem name as defined in get_core_subsystems().   &lt;br /&gt;
&lt;br /&gt;
You can see these being used in the @package parameter in phpdocs, or in the [[Web_services_Roadmap|webservice function names]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Core subsystem&lt;br /&gt;
! Frankenstyle component name&lt;br /&gt;
|-&lt;br /&gt;
| Access&lt;br /&gt;
| core_access&lt;br /&gt;
|-&lt;br /&gt;
| Antivirus&lt;br /&gt;
| core_antivirus&lt;br /&gt;
|-&lt;br /&gt;
| Badges&lt;br /&gt;
| core_badges&lt;br /&gt;
|-&lt;br /&gt;
| Conditional availability&lt;br /&gt;
| core_condition&lt;br /&gt;
|-&lt;br /&gt;
| Comment&lt;br /&gt;
| core_comment&lt;br /&gt;
|-&lt;br /&gt;
| Completion&lt;br /&gt;
| core_completion&lt;br /&gt;
|-&lt;br /&gt;
| Course&lt;br /&gt;
| core_course&lt;br /&gt;
|-&lt;br /&gt;
| Enrol&lt;br /&gt;
| core_enrol&lt;br /&gt;
|-&lt;br /&gt;
| Files&lt;br /&gt;
| core_files&lt;br /&gt;
|-&lt;br /&gt;
| Forms&lt;br /&gt;
| core_form&lt;br /&gt;
|-&lt;br /&gt;
| Grade&lt;br /&gt;
| core_grade&lt;br /&gt;
|-&lt;br /&gt;
| Groups&lt;br /&gt;
| core_group&lt;br /&gt;
|-&lt;br /&gt;
| Messages&lt;br /&gt;
| core_message&lt;br /&gt;
|-&lt;br /&gt;
| Mnet&lt;br /&gt;
| core_mnet&lt;br /&gt;
|-&lt;br /&gt;
| My home page&lt;br /&gt;
| core_my&lt;br /&gt;
|-&lt;br /&gt;
| Notes&lt;br /&gt;
| core_notes&lt;br /&gt;
|-&lt;br /&gt;
| Ratings&lt;br /&gt;
| core_rating&lt;br /&gt;
|-&lt;br /&gt;
| Role&lt;br /&gt;
| core_role&lt;br /&gt;
|-&lt;br /&gt;
| RSS&lt;br /&gt;
| core_rss&lt;br /&gt;
|-&lt;br /&gt;
| Tag&lt;br /&gt;
| core_tag&lt;br /&gt;
|-&lt;br /&gt;
| User&lt;br /&gt;
| core_user&lt;br /&gt;
|-&lt;br /&gt;
| Web service&lt;br /&gt;
| core_webservice&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Usage ==&lt;br /&gt;
&lt;br /&gt;
Frankenstyle component names are used in:&lt;br /&gt;
&lt;br /&gt;
=== Function names ===&lt;br /&gt;
&lt;br /&gt;
All plugin functions must start with full frankenstyle prefix. For backwards compatibility modules may also use &#039;&#039;&#039;modulename_&#039;&#039;&#039; as prefix.&lt;br /&gt;
&lt;br /&gt;
=== Class names ===&lt;br /&gt;
&lt;br /&gt;
All plugin classes must start frankenstyle prefix, ex: mod_forum_some_class.&lt;br /&gt;
&lt;br /&gt;
=== Constants ===&lt;br /&gt;
&lt;br /&gt;
All plugin constants must start with uppercase frankenstyle prefix, example MOD_FORUM_XXXX.&lt;br /&gt;
&lt;br /&gt;
=== Table names ===&lt;br /&gt;
&lt;br /&gt;
All table names for a plugin must begin with its frankenstyle name (after the standard Moodle table prefix).  &lt;br /&gt;
&lt;br /&gt;
(The exception to this rule is Moodle activities which (for historical reasons) do not have mod_ in front of the plugin name)&lt;br /&gt;
&lt;br /&gt;
Examples: mdl_&#039;&#039;&#039;local_coolreport&#039;&#039;&#039;, mdl_&#039;&#039;&#039;local_coolreport&#039;&#039;&#039;_users&lt;br /&gt;
&lt;br /&gt;
=== Plugin configuration table ===&lt;br /&gt;
&lt;br /&gt;
In the &#039;&#039;&#039;config_plugins&#039;&#039;&#039; table, column &#039;&#039;&#039;plugin&#039;&#039;&#039;, the frankenstyle name is used.&lt;br /&gt;
&lt;br /&gt;
=== Capabilities ===&lt;br /&gt;
&lt;br /&gt;
All capabilities for a plugin use the frankenstyle name, except with a / instead of a _.&lt;br /&gt;
&lt;br /&gt;
Example: &#039;&#039;&#039;mod/quiz&#039;&#039;&#039;:viewattempt&lt;br /&gt;
&lt;br /&gt;
=== Language files===&lt;br /&gt;
&lt;br /&gt;
The main language file for each plugin (with the notable exception of activity modules) is the frankenstyle component name. &lt;br /&gt;
&lt;br /&gt;
Examples:  /blocks/participants/lang/en/&#039;&#039;&#039;block_participants&#039;&#039;&#039;.php&lt;br /&gt;
&lt;br /&gt;
=== Renderers ===&lt;br /&gt;
&lt;br /&gt;
=== Module Subplugins ===&lt;br /&gt;
&lt;br /&gt;
It is possible to extend modules without having to change the basic module&#039;s code. See [[Subplugins]] for details.&lt;br /&gt;
&lt;br /&gt;
=== Other places (TODO) ===&lt;br /&gt;
&lt;br /&gt;
* @package declarations in phpdocs, see [[Coding_style#PHPDoc]]&lt;br /&gt;
* [[Web_services_Roadmap|web service function names]]&lt;br /&gt;
* [http://moodle.org Moodle Plugins database]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Please add more as they come up.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Plugins]]&lt;br /&gt;
* [[Subplugins]]&lt;br /&gt;
* [[Core APIs]]&lt;br /&gt;
* [[Automatic class loading]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Plugins]]&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Plugin_types&amp;diff=50258</id>
		<title>Plugin types</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Plugin_types&amp;diff=50258"/>
		<updated>2016-05-23T15:39:45Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: Add Antivirus plugins&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Plugins development}}&lt;br /&gt;
&lt;br /&gt;
The M in Moodle stands for modular.  The easiest and most maintainable way to add new functionality to Moodle is by writing one of these types of plugin. &lt;br /&gt;
If none of the standardized types fits your needs, you can use the &amp;quot;local&amp;quot; type.&lt;br /&gt;
&lt;br /&gt;
== List of Moodle plugin types ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Plugin type&lt;br /&gt;
! Component name ([[Frankenstyle]])&lt;br /&gt;
! Moodle path&lt;br /&gt;
! Description&lt;br /&gt;
! Moodle versions&lt;br /&gt;
|-&lt;br /&gt;
| [[Activity modules]]&lt;br /&gt;
| mod&lt;br /&gt;
| /mod&lt;br /&gt;
| Activity modules are essential types of plugins in Moodle as they provide activities in courses. For example: Forum, Quiz and Assignment.&lt;br /&gt;
| 1.0+&lt;br /&gt;
|-&lt;br /&gt;
| [[Antivirus plugins]]&lt;br /&gt;
| antivirus&lt;br /&gt;
| /lib/antivirus&lt;br /&gt;
| Antivirus scanner plugins provide virus scanning functionality using third-party virus scanning tools in Moodle. For example: ClamAV.&lt;br /&gt;
| 3.1+&lt;br /&gt;
|-&lt;br /&gt;
| [[Assign_submission_plugins|Assignment submission plugins]]&lt;br /&gt;
| assignsubmission&lt;br /&gt;
| /mod/assign/submission&lt;br /&gt;
| Different forms of assignment submissions&lt;br /&gt;
| 2.3+&lt;br /&gt;
|-&lt;br /&gt;
| [[Assign_feedback_plugins|Assignment feedback plugins]]&lt;br /&gt;
| assignfeedback&lt;br /&gt;
| /mod/assign/feedback&lt;br /&gt;
| Different forms of assignment feedbacks&lt;br /&gt;
| 2.3+&lt;br /&gt;
|-&lt;br /&gt;
| [[Book tools]]&lt;br /&gt;
| booktool&lt;br /&gt;
| /mod/book/tool&lt;br /&gt;
| Small information-displays or tools that can be moved around pages&lt;br /&gt;
| 2.1+&lt;br /&gt;
|-&lt;br /&gt;
| [[Database fields]]&lt;br /&gt;
| datafield&lt;br /&gt;
| /mod/data/field&lt;br /&gt;
| Different types of data that may be added to the Database activity module&lt;br /&gt;
| 1.6+&lt;br /&gt;
|-&lt;br /&gt;
| [[Database presets]]&lt;br /&gt;
| datapreset&lt;br /&gt;
| /mod/data/preset&lt;br /&gt;
| Pre-defined templates for the Database activity module&lt;br /&gt;
| 1.6+&lt;br /&gt;
|-&lt;br /&gt;
| [[External tool source|LTI sources]]&lt;br /&gt;
| ltisource&lt;br /&gt;
| /mod/lti/source&lt;br /&gt;
| LTI providers can be added to external tools easily through the external tools interface see [https://docs.moodle.org/en/External_tool Documentation on External Tools]. This type of plugin is specific to LTI providers that need a plugin that can register custom handlers to process LTI messages&lt;br /&gt;
| 2.7+&lt;br /&gt;
|-&lt;br /&gt;
| [[LTI services]]&lt;br /&gt;
| ltiservice&lt;br /&gt;
| /mod/lti/service&lt;br /&gt;
| Allows the implementation of LTI services as described by the IMS LTI specification&lt;br /&gt;
| 2.8+&lt;br /&gt;
|-&lt;br /&gt;
| [[Quiz reports]]&lt;br /&gt;
| quiz&lt;br /&gt;
| /mod/quiz/report&lt;br /&gt;
| Display and analyse the results of quizzes, or just plug miscellaneous behaviour into the quiz module&lt;br /&gt;
| 1.1+&lt;br /&gt;
|-&lt;br /&gt;
| [[Quiz access rules]]&lt;br /&gt;
| quizaccess&lt;br /&gt;
| /mod/quiz/accessrule&lt;br /&gt;
| Add conditions to when or where quizzes can be attempted, for example only from some IP addresses, or student must enter a password first&lt;br /&gt;
| 2.2+&lt;br /&gt;
|-&lt;br /&gt;
| [[SCORM reports]]&lt;br /&gt;
| scormreport&lt;br /&gt;
| /mod/scorm/report&lt;br /&gt;
| Analysis of SCORM attempts&lt;br /&gt;
| 2.2+&lt;br /&gt;
|-&lt;br /&gt;
| [[Workshop grading strategies]]&lt;br /&gt;
| workshopform&lt;br /&gt;
| /mod/workshop/form&lt;br /&gt;
| Define the type of the grading form and implement the calculation of the grade for submission in the [[Workshop]] module&lt;br /&gt;
| 2.0+&lt;br /&gt;
|-&lt;br /&gt;
| [[Workshop allocation methods]]&lt;br /&gt;
| workshopallocation&lt;br /&gt;
| /mod/workshop/allocation&lt;br /&gt;
| Define ways how submissions are assigned for assessment in the [[Workshop]] module&lt;br /&gt;
| 2.0+&lt;br /&gt;
|-&lt;br /&gt;
| [[Workshop evaluation methods]]&lt;br /&gt;
| workshopeval&lt;br /&gt;
| /mod/workshop/eval&lt;br /&gt;
| Implement the calculation of the grade for assessment (grading grade) in the [[Workshop]] module&lt;br /&gt;
| 2.0+&lt;br /&gt;
|-&lt;br /&gt;
| [[Blocks]]&lt;br /&gt;
| block&lt;br /&gt;
| /blocks&lt;br /&gt;
| Small information-displays or tools that can be moved around pages&lt;br /&gt;
| 2.0+&lt;br /&gt;
|-&lt;br /&gt;
| [[Question types]]&lt;br /&gt;
| qtype&lt;br /&gt;
| /question/type&lt;br /&gt;
| Different types of question (e.g. multiple-choice, drag-and-drop) that can be used in quizzes and other activities&lt;br /&gt;
| 1.6+&lt;br /&gt;
|-&lt;br /&gt;
| [[Question behaviours]]&lt;br /&gt;
| qbehaviour&lt;br /&gt;
| /question/behaviour&lt;br /&gt;
| Control how student interact with questions during an attempt&lt;br /&gt;
| 2.1+&lt;br /&gt;
|-&lt;br /&gt;
| [[Question formats|Question import/export formats]]&lt;br /&gt;
| qformat&lt;br /&gt;
| /question/format&lt;br /&gt;
| Import and export question definitions to/from the question bank&lt;br /&gt;
| 1.6+&lt;br /&gt;
|-&lt;br /&gt;
| [[Filters|Text filters]]&lt;br /&gt;
| filter&lt;br /&gt;
| /filter&lt;br /&gt;
| Automatically convert, highlight, and transmogrify text posted into Moodle.&lt;br /&gt;
| 1.4+&lt;br /&gt;
|-&lt;br /&gt;
| [[Editors]]&lt;br /&gt;
| editor&lt;br /&gt;
| /lib/editor&lt;br /&gt;
| Alternative text editors for editing content&lt;br /&gt;
| 2.0+&lt;br /&gt;
|-&lt;br /&gt;
| [[Atto|Atto editor plugins]]&lt;br /&gt;
| atto&lt;br /&gt;
| /lib/editor/atto/plugins&lt;br /&gt;
| Extra functionality for the Atto text editor&lt;br /&gt;
| 2.7+&lt;br /&gt;
|-&lt;br /&gt;
| [[TinyMCE editor plugins]]&lt;br /&gt;
| tinymce&lt;br /&gt;
| /lib/editor/tinymce/plugins&lt;br /&gt;
| Extra functionality for the TinyMCE text editor.&lt;br /&gt;
| 2.4+&lt;br /&gt;
|-&lt;br /&gt;
| [[Enrolment plugins]]&lt;br /&gt;
| enrol&lt;br /&gt;
| /enrol&lt;br /&gt;
| Ways to control who is enrolled in courses&lt;br /&gt;
| 2.0+&lt;br /&gt;
|-&lt;br /&gt;
| [[Authentication plugins]]&lt;br /&gt;
| auth&lt;br /&gt;
| /auth&lt;br /&gt;
| Allows connection to external sources of authentication&lt;br /&gt;
| 2.0+&lt;br /&gt;
|-&lt;br /&gt;
| [[Admin tools]]&lt;br /&gt;
| tool&lt;br /&gt;
| /admin/tool&lt;br /&gt;
| Provides utility scripts useful for various site administration and maintenance tasks&lt;br /&gt;
| 2.2+&lt;br /&gt;
|-&lt;br /&gt;
| [[Log stores]]&lt;br /&gt;
| logstore&lt;br /&gt;
| /admin/tool/log/store&lt;br /&gt;
| Event logs storage back-ends&lt;br /&gt;
| 2.7+&lt;br /&gt;
|-&lt;br /&gt;
| [[Antivirus plugins]]&lt;br /&gt;
| antivirus&lt;br /&gt;
| /lib/antivirus&lt;br /&gt;
| Infrastructure for scanning and detecting viruses in user uploaded files&lt;br /&gt;
| 3.1+&lt;br /&gt;
|-&lt;br /&gt;
| [[Availability conditions]]&lt;br /&gt;
| availability&lt;br /&gt;
| /availability/condition&lt;br /&gt;
| Conditions to restrict user access to activities and sections.&lt;br /&gt;
| 2.7+&lt;br /&gt;
|-&lt;br /&gt;
| [[Calendar types]]&lt;br /&gt;
| calendartype&lt;br /&gt;
| /calendar/type&lt;br /&gt;
| Defines how dates are displayed throughout Moodle&lt;br /&gt;
| 2.6+&lt;br /&gt;
|-&lt;br /&gt;
| [[Messaging consumers]]&lt;br /&gt;
| message&lt;br /&gt;
| /message/output&lt;br /&gt;
| Represent various targets where messages and notifications can be sent to (email, sms, jabber, ...)&lt;br /&gt;
| 2.0+&lt;br /&gt;
|-&lt;br /&gt;
| [[Course formats]]&lt;br /&gt;
| format&lt;br /&gt;
| /course/format&lt;br /&gt;
| Different ways of laying out the activities and blocks in a course&lt;br /&gt;
| 1.3+&lt;br /&gt;
|-&lt;br /&gt;
| [[Data formats]]&lt;br /&gt;
| dataformat&lt;br /&gt;
| /dataformat&lt;br /&gt;
| Formats for data exporting and downloading&lt;br /&gt;
| 3.1+&lt;br /&gt;
|-&lt;br /&gt;
| [[User profile fields]]&lt;br /&gt;
| profilefield&lt;br /&gt;
| /user/profile/field&lt;br /&gt;
| Add new types of data to user profiles&lt;br /&gt;
| 1.9+&lt;br /&gt;
|-&lt;br /&gt;
| [[Reports]]&lt;br /&gt;
| report&lt;br /&gt;
| /report&lt;br /&gt;
| Provides useful views of data in a Moodle site for admins and teachers&lt;br /&gt;
| 2.2+&lt;br /&gt;
|-&lt;br /&gt;
| [[Course reports]]&lt;br /&gt;
| coursereport&lt;br /&gt;
| /course/report&lt;br /&gt;
| Reports of activity within the course&lt;br /&gt;
| Up to 2.1 (for 2.2+ see [[Reports]])&lt;br /&gt;
|-&lt;br /&gt;
| [[Gradebook export]]&lt;br /&gt;
| gradeexport&lt;br /&gt;
| /grade/export&lt;br /&gt;
| Export grades in various formats&lt;br /&gt;
| 1.9+&lt;br /&gt;
|-&lt;br /&gt;
| [[Gradebook import]]&lt;br /&gt;
| gradeimport&lt;br /&gt;
| /grade/import&lt;br /&gt;
| Import grades in various formats &lt;br /&gt;
| 1.9+&lt;br /&gt;
|-&lt;br /&gt;
| [[Gradebook reports]]&lt;br /&gt;
| gradereport&lt;br /&gt;
| /grade/report&lt;br /&gt;
| Display/edit grades in various layouts and reports&lt;br /&gt;
| 1.9+&lt;br /&gt;
|-&lt;br /&gt;
| [[Grading methods|Advanced grading methods]]&lt;br /&gt;
| gradingform&lt;br /&gt;
| /grade/grading/form&lt;br /&gt;
| Interfaces for actually performing grading in activity modules (eg Rubrics)&lt;br /&gt;
| 2.2+&lt;br /&gt;
|-&lt;br /&gt;
| [[MNet services]]&lt;br /&gt;
| mnetservice&lt;br /&gt;
| /mnet/service&lt;br /&gt;
| Allows to implement remote services for the [[MNet]] environment (deprecated, use web services instead)&lt;br /&gt;
| 2.0+&lt;br /&gt;
|-&lt;br /&gt;
| [[Webservice protocols]]&lt;br /&gt;
| webservice&lt;br /&gt;
| /webservice&lt;br /&gt;
| Define new protocols for web service communication (such as SOAP, XML-RPC, JSON, REST ...)&lt;br /&gt;
| 2.0+&lt;br /&gt;
|-&lt;br /&gt;
| [[Repository plugins]]&lt;br /&gt;
| repository&lt;br /&gt;
| /repository&lt;br /&gt;
| Connect to external sources of files to use in Moodle&lt;br /&gt;
| 2.0+&lt;br /&gt;
|-&lt;br /&gt;
| [[Portfolio plugins]]&lt;br /&gt;
| portfolio&lt;br /&gt;
| /portfolio&lt;br /&gt;
| Connect external portfolio services as destinations for users to store Moodle content&lt;br /&gt;
| 1.9+&lt;br /&gt;
|-&lt;br /&gt;
| [[Search engines]]&lt;br /&gt;
| search&lt;br /&gt;
| /search/engine&lt;br /&gt;
| Search engine backends to index Moodle&#039;s contents.&lt;br /&gt;
| 3.1+&lt;br /&gt;
|-&lt;br /&gt;
| [[Plagiarism plugins]]&lt;br /&gt;
| plagiarism&lt;br /&gt;
| /plagiarism&lt;br /&gt;
| Define external services to process submitted files and content&lt;br /&gt;
| 2.0+&lt;br /&gt;
|-&lt;br /&gt;
| [[Cache store]]&lt;br /&gt;
| cachestore&lt;br /&gt;
| /cache/stores&lt;br /&gt;
| Cache storage back-ends.&lt;br /&gt;
| 2.4+&lt;br /&gt;
|-&lt;br /&gt;
| [[Cache locks]]&lt;br /&gt;
| cachelock&lt;br /&gt;
| /cache/locks&lt;br /&gt;
| Cache lock implementations.&lt;br /&gt;
| 2.4+&lt;br /&gt;
|-&lt;br /&gt;
| [[Themes]]&lt;br /&gt;
| theme&lt;br /&gt;
| /theme&lt;br /&gt;
| Change the look of Moodle by changing the the HTML and the CSS. &lt;br /&gt;
| 2.0+&lt;br /&gt;
|-&lt;br /&gt;
| [[Local plugins]]&lt;br /&gt;
| local&lt;br /&gt;
| /local&lt;br /&gt;
| Generic plugins for local customisations&lt;br /&gt;
| 2.0+&lt;br /&gt;
|-&lt;br /&gt;
| [[Assignment types|Legacy assignment types]]&lt;br /&gt;
| assignment&lt;br /&gt;
| /mod/assignment/type&lt;br /&gt;
| Different forms of assignments to be graded by teachers&lt;br /&gt;
| 1.x - 2.2&lt;br /&gt;
|-&lt;br /&gt;
| [[Admin reports|Legacy admin reports]]&lt;br /&gt;
| report&lt;br /&gt;
| /admin/report&lt;br /&gt;
| Provides useful views of data in a Moodle site, for admins only.&lt;br /&gt;
| Up to 2.1 (for 2.2+ see [[Reports]])&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Obtaining the list of plugin types known to your Moodle ==&lt;br /&gt;
&lt;br /&gt;
To get the most exact list of types in your version of Moodle, use the following script. Put it to a file in the root directory of your Moodle installation and execute it via command line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
define(&#039;CLI_SCRIPT&#039;, true);&lt;br /&gt;
require(&#039;config.php&#039;);&lt;br /&gt;
&lt;br /&gt;
$pluginman = core_plugin_manager::instance();&lt;br /&gt;
&lt;br /&gt;
foreach ($pluginman-&amp;gt;get_plugin_types() as $type =&amp;gt; $dir) {&lt;br /&gt;
    $dir = substr($dir, strlen($CFG-&amp;gt;dirroot));&lt;br /&gt;
    printf(&amp;quot;%-20s %-50s %s&amp;quot;.PHP_EOL, $type, $pluginman-&amp;gt;plugintype_name_plural($type), $dir);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Things you can find in all plugins==&lt;br /&gt;
&lt;br /&gt;
Although there are many different types of plugin, there are some things that work the same way in all plugin types, and we have [[Things that work the same in all plugin types|a page that describes them]].&lt;br /&gt;
&lt;br /&gt;
Additionally you probably want to look at the page [[Plugin files]].&lt;br /&gt;
&lt;br /&gt;
== Naming conventions ==&lt;br /&gt;
&lt;br /&gt;
Warning if you have to choose a plugin (directory) name. The name is validated by the method &amp;lt;tt&amp;gt;lib/classes/component.php::is_valid_plugin_name()&amp;lt;/tt&amp;gt; with a regexp: &amp;lt;tt&amp;gt;/^[a-z](?:[a-z0-9_](?!__))*[a-z0-9]+$/&amp;lt;/tt&amp;gt;. In particular, the minus (-) character is not considered as valid, and the plugin will be silently ignored if the name is not valid.&lt;br /&gt;
&lt;br /&gt;
There is an exception for [[Activity modules|activity modules]] that can not have the underscore in their name for legacy reasons.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Guidelines_for_contributed_code|Guidelines for contributing code]]&lt;br /&gt;
* [[Core APIs]]&lt;br /&gt;
* [[Frankenstyle]]&lt;br /&gt;
* [http://moodle.org/plugins Moodle Plugins directory] &lt;br /&gt;
&lt;br /&gt;
[[Category:Coding guidelines|Plugins]]&lt;br /&gt;
[[Category:Plugins]]&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Moodle_3.1_release_notes&amp;diff=50256</id>
		<title>Moodle 3.1 release notes</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Moodle_3.1_release_notes&amp;diff=50256"/>
		<updated>2016-05-23T15:25:51Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: /* For developers */ Add antivirus plugin documentation link.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Releases]] &amp;gt; {{FULLPAGENAME}}&lt;br /&gt;
 &lt;br /&gt;
Release date: 23 May 2016&lt;br /&gt;
&lt;br /&gt;
Here is [https://tracker.moodle.org/secure/IssueNavigator!executeAdvanced.jspa?jqlQuery=project+%3D+mdl+AND+resolution+%3D+fixed+AND+fixVersion+in+%28%223.1%22%29+ORDER+BY+priority+DESC&amp;amp;runQuery=true&amp;amp;clear=true the full list of fixed issues in 3.1].&lt;br /&gt;
&lt;br /&gt;
See our [https://docs.moodle.org/31/en/New_features New Features page] for a more user-friendly introduction to Moodle 3.1 with screenshots.&lt;br /&gt;
&lt;br /&gt;
If you are upgrading from previous version, make sure you read the [https://docs.moodle.org/31/en/Upgrading Upgrading] documentation. &lt;br /&gt;
&lt;br /&gt;
==Server requirements==&lt;br /&gt;
&lt;br /&gt;
These are just the minimum supported versions. We recommend keeping all of your software up-to-date.&lt;br /&gt;
&lt;br /&gt;
* Moodle upgrade:  Moodle 2.7 or later (if upgrading from earlier versions, you must upgrade to 2.7.14 as a first step)&lt;br /&gt;
* PHP version: minimum PHP 5.4.4 (always use latest PHP 5.4.x , 5.5.x or 5.6.x on Windows - http://windows.php.net/download/). PHP 7 is supported but has some [https://docs.moodle.org/dev/Moodle_and_PHP7#Can_I_use_PHP7_yet.3F engine limitations].&lt;br /&gt;
* Ghostscript should be installed for pdf annotation.&lt;br /&gt;
* Unoconv should be installed for file conversion used by pdf annotations (new in Moodle 3.1)&lt;br /&gt;
* &#039;&#039;&#039;New requirement for Moodle 3.1 comparing to 3.0&#039;&#039;&#039;: PHP extension &amp;lt;tt&amp;gt;xmlreader&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Database requirements ===&lt;br /&gt;
&lt;br /&gt;
Moodle supports the following database servers. Again, version numbers are just the minimum supported version. We recommend running the latest stable version of any software.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Database&lt;br /&gt;
! Minimum version&lt;br /&gt;
! Recommended&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.postgresql.org/ PostgreSQL]&lt;br /&gt;
| 9.1&lt;br /&gt;
| Latest&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mysql.com/ MySQL]&lt;br /&gt;
| 5.5.31&lt;br /&gt;
| Latest&lt;br /&gt;
|-&lt;br /&gt;
| [https://mariadb.org/ MariaDB]&lt;br /&gt;
| 5.5.31&lt;br /&gt;
| Latest&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.microsoft.com/en-us/server-cloud/products/sql-server/ Microsoft SQL Server]&lt;br /&gt;
| 2008&lt;br /&gt;
| Latest&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.oracle.com/us/products/database/overview/index.html Oracle Database]&lt;br /&gt;
| 10.2&lt;br /&gt;
| Latest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Client requirements==&lt;br /&gt;
&lt;br /&gt;
=== Browser support ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Browser&lt;br /&gt;
! Minimum version&lt;br /&gt;
! Recommended version&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| [https://www.google.com/intl/en_au/chrome/browser/ Google Chrome]&lt;br /&gt;
| 30.0&lt;br /&gt;
| Latest&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mozilla.org/en-US/ Mozilla Firefox]&lt;br /&gt;
| 25.0&lt;br /&gt;
| Latest&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.apple.com/safari/ Apple Safari]&lt;br /&gt;
| 6&lt;br /&gt;
| Latest&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| [http://windows.microsoft.com/en-AU/internet-explorer/download-ie Microsoft Internet Explorer]&lt;br /&gt;
| 9&lt;br /&gt;
| Latest&lt;br /&gt;
| Version 10 is required for drag-and-drop upload of content from outside the browser into Moodle&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Major features==&lt;br /&gt;
&lt;br /&gt;
===Highlights===&lt;br /&gt;
&lt;br /&gt;
* MDL-53451 - Competencies support in Moodle&lt;br /&gt;
* MDL-52954 - Improvements to the Assignment grading user interface&lt;br /&gt;
* MDL-31989 - [https://docs.moodle.org/31/en/Global_search Global Search] API allows to search forums, wikis and other content throughout the whole site. [https://docs.moodle.org/31/en/Global_search Installation and setup] of SOLR server is required, &lt;br /&gt;
* MDL-52002 - Significant performance improvements in gradebook calculations&lt;br /&gt;
* MDL-48012 - [https://docs.moodle.org/31/en/Recycle_bin Recycle bin] plugin is now part of standard Moodle distribution: allow instructors to &amp;quot;undo&amp;quot; deletions of course modules and courses. [https://moodleassociation.org/ Moodle Users Association] project&lt;br /&gt;
* MDL-49279 - Add support in moodle plugins for exporting &amp;quot;[[Moodle Mobile Remote add-ons|Mobile app addons]]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
===Forum===&lt;br /&gt;
&lt;br /&gt;
* MDL-372 - Allow to [https://docs.moodle.org/31/en/Using_Forum#Pinned_posts &amp;quot;pin&amp;quot; discussions] to keep them always on the top of the list&lt;br /&gt;
* MDL-34160 - Allow forum email subject to be customised&lt;br /&gt;
* MDL-47365 - Add  [https://docs.moodle.org/31/en/Using_Forum#Permalinks permalink] option to forum posts&lt;br /&gt;
* MDL-51214 - Rename the News forum to [https://docs.moodle.org/31/en/Announcements &amp;quot;Announcements&amp;quot;]&lt;br /&gt;
* MDL-44087 - Forum does not observe message notification settings for digest emails&lt;br /&gt;
* MDL-53050 - Highlight the selected forum post when deep linking with a #anchor&lt;br /&gt;
&lt;br /&gt;
===Assignment===&lt;br /&gt;
&lt;br /&gt;
* MDL-52397 - Feedback for Assignments is not sent if the assignment grade timemodified setting was set to two days ago&lt;br /&gt;
* MDL-52596 - Add a &#039;maxperpage&#039; site wide setting for grading table size (to mitigate broken grading pages in large courses)&lt;br /&gt;
* MDL-52269 - Not obvious to tell if an assignment is in blind marking if user holds the &amp;quot;mod/assign:viewblinddetails&amp;quot; capabilty&lt;br /&gt;
* MDL-52270 - Difficult to cross reference users with their blind identities&lt;br /&gt;
* MDL-44598 - List student names on &#039;grant extension&#039; screen&lt;br /&gt;
* MDL-52490 - Download selected assign submissions as a zip file&lt;br /&gt;
* MDL-52290 - EditPDF - Also show the total page number in the pagination&lt;br /&gt;
* MDL-52489 - &amp;quot;Download all submissions as a zip&amp;quot; should maintain the folder structure in students submissions&lt;br /&gt;
&lt;br /&gt;
===External tool (LTI)===&lt;br /&gt;
&lt;br /&gt;
* MDL-52154 - Rework LTI admin screens&lt;br /&gt;
* MDL-45064 - Option to add Preconfigured LTI Tool to Activity Chooser&lt;br /&gt;
* MDL-52035 - Integrate LTI Provider support in Moodle as the [https://docs.moodle.org/31/en/Publish_as_LTI_tool Publish as LTI tool]&lt;br /&gt;
* MDL-52821 - Compliance: Send tool_consumer_instance_description in LTI launch request&lt;br /&gt;
&lt;br /&gt;
===Feedback===&lt;br /&gt;
&lt;br /&gt;
* MDL-53738 - Feedback activity module will be enabled by default in new 3.1 installations. If you are upgrading to 3.1 we recommend you to enable it manually.&lt;br /&gt;
* MDL-52094 - Various improvements to UI and bug fixes, including:&lt;br /&gt;
** Performance improvement to download responses as raw data in multiple formats (CSV, Excel, etc.) - now available on &amp;quot;Show responses&amp;quot; page instead of &amp;quot;Analysis&amp;quot;&lt;br /&gt;
** Allow any characters in labels, do not display empty labels&lt;br /&gt;
** Do not display empty pages&lt;br /&gt;
** Map frontpage feedback to multiple courses without leaving the form&lt;br /&gt;
** Improved display of automatic question numbers&lt;br /&gt;
** Disable &amp;quot;Response time&amp;quot; for anonymous feedbacks&lt;br /&gt;
** Use moodleforms to display feedback&lt;br /&gt;
&lt;br /&gt;
===SCORM===&lt;br /&gt;
&lt;br /&gt;
* MDL-45712 - Add Result field to the SCORM Interactions Report&lt;br /&gt;
* MDL-48680 - Add score and status submission events to SCORM activity&lt;br /&gt;
* MDL-42473 - Add group support to SCORM activity&lt;br /&gt;
&lt;br /&gt;
===Quiz===&lt;br /&gt;
&lt;br /&gt;
* MDL-52738 - Quiz attempt/review page should have a previous button to match next&lt;br /&gt;
* MDL-46092 - Add the OU styling of the Quiz navigation into Moodle core as the default&lt;br /&gt;
* MDL-46091 - Rationalise confirmations when you start a quiz&lt;br /&gt;
* MDL-52806 - Show right answers when manually grading automatically marked questions&lt;br /&gt;
* MDL-53304 - Immediate feedback behaviours should not show a disabled check button when you can&#039;t use it&lt;br /&gt;
&lt;br /&gt;
===Other activity modules===&lt;br /&gt;
&lt;br /&gt;
* MDL-42190 - Workshop: Possibility to delete a submission&lt;br /&gt;
* MDL-51306 - Folder: [https://docs.moodle.org/31/en/Folder_resource Bulk download all files within a folder activity as ZIP file]&lt;br /&gt;
* MDL-52414 - Lesson: Allow Default Settings for [https://docs.moodle.org/31/en/Lesson_settings Lesson Module Settings]&lt;br /&gt;
* MDL-51267 - URL/File: Make setting up a [https://docs.moodle.org/31/en/URL_resource_settings#General URL]/[https://docs.moodle.org/31/en/File_resource_settings#Uploading_files File] resource more obvious&lt;br /&gt;
* MDL-50794 - Workshop: [https://docs.moodle.org/31/en/Workshop_settings Restricting file types as attachments] to a workshop&lt;br /&gt;
&lt;br /&gt;
===Gradebook===&lt;br /&gt;
&lt;br /&gt;
* MDL-48634 - Option to rescale existing grades when changing max points&lt;br /&gt;
* MDL-52522 - grade_minmaxtouse should be respected for overridden categories&lt;br /&gt;
* MDL-51900 - Tab Down Grade Column in Single View of Gradebook&lt;br /&gt;
* MDL-52309 - Make Grade History report require user to submit parameters before the report starts running&lt;br /&gt;
&lt;br /&gt;
===Performance===&lt;br /&gt;
&lt;br /&gt;
* MDL-51374 - Do not purge entire databasemeta cache when there are structure changes (esp temp tables).&lt;br /&gt;
* MDL-51603 - Refactor downloading of csv, ods, excel etc files in reports and exports across moodle to stream progressively&lt;br /&gt;
* MDL-34925 - Improve bulk user export performance&lt;br /&gt;
* MDL-50385 - Performance improvement to the grade history report&lt;br /&gt;
&lt;br /&gt;
===Tagging===&lt;br /&gt;
&lt;br /&gt;
* MDL-50851 - Introduce tag collections - ability to separate independent tag areas&lt;br /&gt;
* MDL-52252 - Add tags to modules (Resources and Activities)&lt;br /&gt;
* MDL-25742 - Allow to search wiki pages by tags&lt;br /&gt;
* MDL-51283 - Rename &amp;quot;official&amp;quot; tags to &amp;quot;standard&amp;quot;, allow admin to set for each tag area how to use standard tags&lt;br /&gt;
* MDL-16855 - Add tag filtering to &amp;quot;Manage tags&amp;quot; page&lt;br /&gt;
* MDL-52707 - Allow tags to be combined&lt;br /&gt;
&lt;br /&gt;
===Usability===&lt;br /&gt;
&lt;br /&gt;
* MDL-27628 - [https://docs.moodle.org/31/en/Course_meta_link Enrol meta:] Possible to add multiple courses without leaving the form&lt;br /&gt;
* MDL-51818 - Move the profile &#039;Message&#039; button to be next to the user picture&lt;br /&gt;
* MDL-52258 - Calendar now shows duration in calendar block&lt;br /&gt;
* MDL-53043 - Move user search box above the students list in the manual enrolments popup&lt;br /&gt;
* MDL-35590 - Navigation block redesign to meet ARIA specification&lt;br /&gt;
* MDL-49963 - Allow to message all participants when there are more than one page in participants list&lt;br /&gt;
* MDL-51354 - Help popup and improved name for events dropdown menu on the course and site logs pages&lt;br /&gt;
* MDL-53026 - Use inplace editable for editing cohort names&lt;br /&gt;
* MDL-51706 - Move plagiarism links to the top of the summary and full text outputs&lt;br /&gt;
* MDL-53382 - &amp;quot;Show all&amp;quot; link on participants page should be moved beneath the page switcher&lt;br /&gt;
&lt;br /&gt;
===Other improvements===&lt;br /&gt;
&lt;br /&gt;
* MDL-53057 - Add [https://docs.moodle.org/31/en/File_system_repository#Using_a_File_System_repository_file search feature to the File system repository]&lt;br /&gt;
* MDL-48506 - Improve memcached cache store so that it is multi-site safe&lt;br /&gt;
* MDL-50661 - Restyle &amp;quot;Clean&amp;quot; theme to use Logo and Header in Frontpage with smaller logo option in other pages.&lt;br /&gt;
* MDL-36652 - When downloading an Excel spreadsheet of student logs, have the course short name included in the file name. &lt;br /&gt;
* MDL-53207 - Display stock avatar instead of own user picture from messages from fake users&lt;br /&gt;
* MDL-51698 - Markup the crumb trail so search engines understand it and leverage it&lt;br /&gt;
* MDL-53072 - Option to choose whether we include suspended users when auto-creating groups&lt;br /&gt;
* MDL-52869 - Convert inline activity name edit to use the inplace editable element&lt;br /&gt;
&lt;br /&gt;
===For administrators===&lt;br /&gt;
&lt;br /&gt;
* MDL-26935 - New capability to control role renaming&lt;br /&gt;
* MDL-28030 - Add config.php settings to allow plugins to rewrite output moodle_urls (eg clean / semantic urls)&lt;br /&gt;
* MDL-52752 - Administrators can specify an alternate URL to use for MathJax&lt;br /&gt;
* MDL-52219 - Completion tracking &amp;amp; availability should default to on for new installs&lt;br /&gt;
* MDL-52990 - Enable all emails to be themed, ie add 4 wrapper mustache templates&lt;br /&gt;
* MDL-53260 - Option to display CLI upgrade messages in English&lt;br /&gt;
* MDL-52386 - Allow to control field for flagging enabled/disabled users in LDAP authentication (useful for Active Directory)&lt;br /&gt;
* MDL-52383 - Calendar &amp;quot;Days to look ahead&amp;quot; should allow intervals up to 1 year&lt;br /&gt;
* MDL-49934 - Admins or managers should be able to retrieve assignments info via get_assignments web service&lt;br /&gt;
&lt;br /&gt;
==Security issues==&lt;br /&gt;
&lt;br /&gt;
There are no security issues included in this release, please refer to [https://docs.moodle.org/dev/Moodle_3.0.4_release_notes Moodle 3.0.4 release notes]&lt;br /&gt;
&lt;br /&gt;
==For developers==&lt;br /&gt;
&lt;br /&gt;
===Significant new areas===&lt;br /&gt;
&lt;br /&gt;
* MDL-31989 - [https://docs.moodle.org/dev/Search_API Global Search] API allows to index and search forums, wikis and other content throughout the whole site.&lt;br /&gt;
* MDL-49279, MDL-50032 - Add support in moodle plugins for exporting &amp;quot;[[Moodle Mobile Remote add-ons|Mobile app addons]]&amp;quot;&lt;br /&gt;
* MDL-53451 - Competencies support in Moodle ([https://docs.moodle.org/dev/Competency_API documentation])&lt;br /&gt;
* MDL-50887 - Implement plugins infrastructure for antivirus and create ClamAV plugin ([https://docs.moodle.org/dev/Antivirus_plugins documentation]).&lt;br /&gt;
* MDL-51603 - New [https://docs.moodle.org/dev/Data_formats Dataformat] plugin type for downloading data as csv, ods, excel etc (eg from table_sql export)&lt;br /&gt;
* MDL-50851 - Significant changes to Tags API, tag areas can now implement callbacks to display tagged items ([https://docs.moodle.org/dev/Tag_API documentation])&lt;br /&gt;
* MDL-46891 - Upgrade to behat 3.x ([https://docs.moodle.org/dev/Acceptance_testing/Migrating_from_Behat_2.5_to_3.x_in_Moodle documentation])&lt;br /&gt;
&lt;br /&gt;
===Smaller new things===&lt;br /&gt;
&lt;br /&gt;
* MDL-51802 - Reusable element for inplace editing ([https://docs.moodle.org/dev/Inplace_editable documentation])&lt;br /&gt;
* MDL-30811 - Introduce notification stack to moodle sessions ([https://docs.moodle.org/dev/Notifications documentation])&lt;br /&gt;
* MDL-52237 - Add a callback to inject nodes in the user profile navigation&lt;br /&gt;
* MDL-51324 - New course chooser element for moodleforms ([https://docs.moodle.org/dev/lib/formslib.php_Form_Definition#autocomplete documentation])&lt;br /&gt;
* MDL-53311 - Reusable element for displaying tree similar to navigation tree ([https://docs.moodle.org/dev/Tree documentation])&lt;br /&gt;
&lt;br /&gt;
===Smaller changes in core APIs===&lt;br /&gt;
&lt;br /&gt;
* MDL-52954 - file_storage class can now convert between office documents ([https://docs.moodle.org/dev/File_API#Convert_between_file_formats_.28office_documents.29 documentation])&lt;br /&gt;
* MDL-53274 - Throw exception (in developer mode) if page context is not set, otherwise it is easily missed in AJAX calls&lt;br /&gt;
* MDL-52826, MDL-52715 - Allow to use moodleforms in AJAX requests ([https://docs.moodle.org/dev/Fragment documentation])&lt;br /&gt;
* MDL-51718 - Allow to specify scheme in moodle_url&lt;br /&gt;
* MDL-51700 - Ajax service should clean the return values of the external functions&lt;br /&gt;
* MDL-53962 - &#039;&#039;&#039;Changes to webservices XML-RPC API&#039;&#039;&#039; - it is now &#039;&#039;&#039;critical&#039;&#039;&#039; to specify parameters for XML-RPC calls in the correct order. Previously Zend may have been able to work out the order, our new implementation, at this stage, cannot.&lt;br /&gt;
&lt;br /&gt;
===Themeability improvements===&lt;br /&gt;
&lt;br /&gt;
* MDL-50464 - New renderer for RSS Client Block allows themes to customise its look&lt;br /&gt;
&lt;br /&gt;
===Changes related to particular plugins===&lt;br /&gt;
&lt;br /&gt;
* MDL-52013 - Allow mod_assign plugins to add calendar events&lt;br /&gt;
* MDL-48362 - Improve the enrol API to prevent logic in the UI ([https://docs.moodle.org/dev/Enrolment_plugins#Standard_Editing_UI documentation])&lt;br /&gt;
* MDL-52996 - Allow Atto customisation for special-purpose plugins&lt;br /&gt;
* MDL-52781 - Improved validation on user fields when creating users from external datasources&lt;br /&gt;
* MDL-53304 - Changes to interactive question behaviour may cause the unit tests for your question type to break if you have followed the common patter. You will need to make changes like [https://github.com/moodle/moodle/commit/81e47a35e8bb98a94ea88e45eee63dcda1b46f74#diff-d16a78021131604bb14ae59ebe6eeebbL235 this].&lt;br /&gt;
&lt;br /&gt;
===Deprecations===&lt;br /&gt;
&lt;br /&gt;
For full list of deprecations refer to lib/upgrade.txt and upgrade.txt files in the folder where the particular plugin is located. Here are the most major deprecations:&lt;br /&gt;
&lt;br /&gt;
* MDL-49414 - Remove deprecated web services&lt;br /&gt;
* MDL-48621 - Deprecate the old events system&lt;br /&gt;
* MDL-52207 - Delete Zend framework&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
*[[Moodle 3.0 release notes]]&lt;br /&gt;
 &lt;br /&gt;
[[Category:Release notes]]&lt;br /&gt;
[[Category:Moodle 3.1]]&lt;br /&gt;
 &lt;br /&gt;
[[fr:Notes de mise à jour de Moodle 3.1]]&lt;br /&gt;
[[es:Notas de Moodle 3.1]]&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Antivirus_plugins&amp;diff=50255</id>
		<title>Antivirus plugins</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Antivirus_plugins&amp;diff=50255"/>
		<updated>2016-05-23T15:20:50Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: /* Example */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 3.1}}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
Antivirus plugins implement virus scanning functionality in Moodle. This allows external contributor to develop plugins for different antivirus products and extend existing antivirus functionality to different areas of Moodle. The plugin for ClamAV antivirus tool is included in the core.&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
&lt;br /&gt;
Antivirus scanning using ClamAV has been initially introduced in Moodle 1.3 in the [https://github.com/moodle/moodle/commit/18b8fbfa patchset] committed by Penny Leach. Since that time, the code has been refactored a number of times to match File and Repository API changes, however always remained limited to ClamAV antivirus product. In Moodle 3.1 antivirus scanning has been re-introduced as a separate plugin type with ClamAV plugin included in the core.&lt;br /&gt;
&lt;br /&gt;
== Current status ==&lt;br /&gt;
&lt;br /&gt;
The antivirus functionality is ongoing work, covered in MDL-50886. It most likely there will be some more API changes in upcoming release.&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
&lt;br /&gt;
The best example of antivirus plugin is ClamAV antivirus scanner plugin included in the core (&amp;lt;tt&amp;gt;[https://github.com/moodle/moodle/tree/MOODLE_31_STABLE/lib/antivirus/clamav /lib/antivirus/clamav]&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
== File structure ==&lt;br /&gt;
&lt;br /&gt;
All files for an antivirus plugin go within &amp;lt;tt&amp;gt;/lib/antivirus/name&amp;lt;/tt&amp;gt;, where &amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt; is the name of the antivirus plugin, e.g. for ScanMyFile plugin used in examples below, the file structure will be as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 lib/antivirus/scanmyfile/&lt;br /&gt;
 |-- classes&lt;br /&gt;
 |   `-- scanner.php&lt;br /&gt;
 |-- db&lt;br /&gt;
 |   `-- upgrade.php&lt;br /&gt;
 |-- lang&lt;br /&gt;
 |   `-- en&lt;br /&gt;
 |       `-- antivirus_scanmyfile.php&lt;br /&gt;
 |-- settings.php&lt;br /&gt;
 |-- tests&lt;br /&gt;
 |   `-- scanner_test.php&lt;br /&gt;
 `-- version.php&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== version.php ===&lt;br /&gt;
&lt;br /&gt;
Standard [[version.php]] for the plugin.&lt;br /&gt;
&lt;br /&gt;
=== settings.php ===&lt;br /&gt;
&lt;br /&gt;
Standard [[Admin_settings]] for the plugin configuration, make sure plugin configuration is stored in &amp;lt;tt&amp;gt;config_plugins&amp;lt;/tt&amp;gt; table.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if ($ADMIN-&amp;gt;fulltree) {&lt;br /&gt;
    $settings-&amp;gt;add(new admin_setting_configexecutable(&#039;antivirus_scanmyfile/pathtoscanner&#039;,&lt;br /&gt;
            new lang_string(&#039;pathtoscanner&#039;, &#039;antivirus_scanmyfile&#039;), new lang_string(&#039;configpathtoscanner&#039;, &#039;antivirus_scanmyfile&#039;), &#039;&#039;));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== lang/en/antivirus_scanmyfile.php ===&lt;br /&gt;
&lt;br /&gt;
Language strings for the plugin. Required strings:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;pluginname&#039;&#039;&#039; - name of plugin.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$string[&#039;pluginname&#039;] = &#039;SanMyFile antivirus&#039;;&lt;br /&gt;
$string[&#039;pathtoscanner&#039;] = &#039;Path to scanner&#039;;&lt;br /&gt;
$string[&#039;configpathtoscanner&#039;] = &#039;Define full path to scanner&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will usually need to add your own strings for two main purposes:&lt;br /&gt;
&lt;br /&gt;
* Adding configuration settings.&lt;br /&gt;
* Displaying information about scanning errors.&lt;br /&gt;
&lt;br /&gt;
=== db (directory) ===&lt;br /&gt;
&lt;br /&gt;
Standard upgrade/install routines for plugin.&lt;br /&gt;
&lt;br /&gt;
=== classes/scanner.php ===&lt;br /&gt;
&lt;br /&gt;
The file contains &amp;lt;tt&amp;gt;scanner&amp;lt;/tt&amp;gt; class defined in &amp;lt;tt&amp;gt;antivirus_name&amp;lt;/tt&amp;gt; namespace, that extends &amp;lt;tt&amp;gt;\core\antivirus\scanner&amp;lt;/tt&amp;gt; class and implements the back-end for the antivirus scanning. It is expected that the class will contain at least two methods:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt&amp;gt;is_configured()&amp;lt;/tt&amp;gt; - returns true, if this antivirus plugin is configured.&lt;br /&gt;
* &amp;lt;tt&amp;gt;scan_file($file, $filename, $deleteinfected)&amp;lt;/tt&amp;gt; - performs the &#039;&#039;$file&#039;&#039; scanning using antivirus functionality, using &#039;&#039;$filename&#039;&#039; as filename string in any reporting, deletes infected file if &#039;&#039;$deleteinfected&#039;&#039; is true.&lt;br /&gt;
&lt;br /&gt;
It is expected that &amp;lt;tt&amp;gt;scan_file()&amp;lt;/tt&amp;gt; function will throw exception of &amp;lt;tt&amp;gt;\core\antivirus\scanner_exception&amp;lt;/tt&amp;gt; type if virus is found, otherwise will return &#039;&#039;void&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The simplified example of scanner.php is shown below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// You must use the right namespace (matching your plugin antivirus name).&lt;br /&gt;
namespace antivirus_scanmyfile;&lt;br /&gt;
&lt;br /&gt;
defined(&#039;MOODLE_INTERNAL&#039;) || die();&lt;br /&gt;
&lt;br /&gt;
class scanner extends \core\antivirus\scanner {&lt;br /&gt;
&lt;br /&gt;
    public function is_configured() {&lt;br /&gt;
        // Parent&#039;s get_config() function is effectively a wrapper of get_config(&#039;antivirus_scanmyfile&#039;, &#039;somesettingname&#039;) call.&lt;br /&gt;
        return (bool)$this-&amp;gt;get_config(&#039;pathtoscanner&#039;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public function scan_file($file, $filename, $deleteinfected) {&lt;br /&gt;
        if (!is_readable($file)) {&lt;br /&gt;
            // This should not happen.&lt;br /&gt;
            debugging(&#039;File is not readable.&#039;);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Execute the scan using antivirus own scanning tool, we assume it returns 0 if no virus is found, 1 if file is infected, any other number on error.&lt;br /&gt;
        $return = $this-&amp;gt;scan_file_using_scanmyfile_scanner_tool($file);&lt;br /&gt;
&lt;br /&gt;
        if ($return == 0) {&lt;br /&gt;
            // Perfect, no problem found, file is clean.&lt;br /&gt;
            return;&lt;br /&gt;
        } else if ($return == 1) {&lt;br /&gt;
            // Infection found.&lt;br /&gt;
            if ($deleteinfected) {&lt;br /&gt;
                unlink($file);&lt;br /&gt;
            }&lt;br /&gt;
            throw new \core\antivirus\scanner_exception(&#039;virusfounduser&#039;, &#039;&#039;, array(&#039;filename&#039; =&amp;gt; $filename));&lt;br /&gt;
        } else {&lt;br /&gt;
            // Unknown problem.&lt;br /&gt;
            debugging(&#039;Error occurred during file scanning.&#039;);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public function scan_file_using_scanmyfile_scanner_tool($file) {&lt;br /&gt;
        // Scanning routine using antivirus own tool goes here.&lt;br /&gt;
        // ...&lt;br /&gt;
        // For example purposes, we assume it returns 0 if no virus is found, 1 if file is infected, any other number on error.&lt;br /&gt;
        return $return;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== tests/scanner_test.php (optional) ===&lt;br /&gt;
&lt;br /&gt;
Normally you would write a unit test for the antivirus plugin inside this file. Since plugin rely on external tool, it might be a good idea to replace real component with &amp;quot;double&amp;quot;. See ClamAV plugin for example and PHPUnit [https://phpunit.de/manual/current/en/test-doubles.html manual section].&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Antivirus_plugins&amp;diff=50254</id>
		<title>Antivirus plugins</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Antivirus_plugins&amp;diff=50254"/>
		<updated>2016-05-23T15:19:31Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: /* classes/scanner.php */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 3.1}}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
Antivirus plugins implement virus scanning functionality in Moodle. This allows external contributor to develop plugins for different antivirus products and extend existing antivirus functionality to different areas of Moodle. The plugin for ClamAV antivirus tool is included in the core.&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
&lt;br /&gt;
Antivirus scanning using ClamAV has been initially introduced in Moodle 1.3 in the [https://github.com/moodle/moodle/commit/18b8fbfa patchset] committed by Penny Leach. Since that time, the code has been refactored a number of times to match File and Repository API changes, however always remained limited to ClamAV antivirus product. In Moodle 3.1 antivirus scanning has been re-introduced as a separate plugin type with ClamAV plugin included in the core.&lt;br /&gt;
&lt;br /&gt;
== Current status ==&lt;br /&gt;
&lt;br /&gt;
The antivirus functionality is ongoing work, covered in MDL-50886. It most likely there will be some more API changes in upcoming release.&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
&lt;br /&gt;
The best example of antivirus plugin is ClamAV antivirus scanner plugin included in the core (&amp;lt;tt&amp;gt;/lib/antivirus/clamav&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
== File structure ==&lt;br /&gt;
&lt;br /&gt;
All files for an antivirus plugin go within &amp;lt;tt&amp;gt;/lib/antivirus/name&amp;lt;/tt&amp;gt;, where &amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt; is the name of the antivirus plugin, e.g. for ScanMyFile plugin used in examples below, the file structure will be as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 lib/antivirus/scanmyfile/&lt;br /&gt;
 |-- classes&lt;br /&gt;
 |   `-- scanner.php&lt;br /&gt;
 |-- db&lt;br /&gt;
 |   `-- upgrade.php&lt;br /&gt;
 |-- lang&lt;br /&gt;
 |   `-- en&lt;br /&gt;
 |       `-- antivirus_scanmyfile.php&lt;br /&gt;
 |-- settings.php&lt;br /&gt;
 |-- tests&lt;br /&gt;
 |   `-- scanner_test.php&lt;br /&gt;
 `-- version.php&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== version.php ===&lt;br /&gt;
&lt;br /&gt;
Standard [[version.php]] for the plugin.&lt;br /&gt;
&lt;br /&gt;
=== settings.php ===&lt;br /&gt;
&lt;br /&gt;
Standard [[Admin_settings]] for the plugin configuration, make sure plugin configuration is stored in &amp;lt;tt&amp;gt;config_plugins&amp;lt;/tt&amp;gt; table.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if ($ADMIN-&amp;gt;fulltree) {&lt;br /&gt;
    $settings-&amp;gt;add(new admin_setting_configexecutable(&#039;antivirus_scanmyfile/pathtoscanner&#039;,&lt;br /&gt;
            new lang_string(&#039;pathtoscanner&#039;, &#039;antivirus_scanmyfile&#039;), new lang_string(&#039;configpathtoscanner&#039;, &#039;antivirus_scanmyfile&#039;), &#039;&#039;));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== lang/en/antivirus_scanmyfile.php ===&lt;br /&gt;
&lt;br /&gt;
Language strings for the plugin. Required strings:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;pluginname&#039;&#039;&#039; - name of plugin.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$string[&#039;pluginname&#039;] = &#039;SanMyFile antivirus&#039;;&lt;br /&gt;
$string[&#039;pathtoscanner&#039;] = &#039;Path to scanner&#039;;&lt;br /&gt;
$string[&#039;configpathtoscanner&#039;] = &#039;Define full path to scanner&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will usually need to add your own strings for two main purposes:&lt;br /&gt;
&lt;br /&gt;
* Adding configuration settings.&lt;br /&gt;
* Displaying information about scanning errors.&lt;br /&gt;
&lt;br /&gt;
=== db (directory) ===&lt;br /&gt;
&lt;br /&gt;
Standard upgrade/install routines for plugin.&lt;br /&gt;
&lt;br /&gt;
=== classes/scanner.php ===&lt;br /&gt;
&lt;br /&gt;
The file contains &amp;lt;tt&amp;gt;scanner&amp;lt;/tt&amp;gt; class defined in &amp;lt;tt&amp;gt;antivirus_name&amp;lt;/tt&amp;gt; namespace, that extends &amp;lt;tt&amp;gt;\core\antivirus\scanner&amp;lt;/tt&amp;gt; class and implements the back-end for the antivirus scanning. It is expected that the class will contain at least two methods:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt&amp;gt;is_configured()&amp;lt;/tt&amp;gt; - returns true, if this antivirus plugin is configured.&lt;br /&gt;
* &amp;lt;tt&amp;gt;scan_file($file, $filename, $deleteinfected)&amp;lt;/tt&amp;gt; - performs the &#039;&#039;$file&#039;&#039; scanning using antivirus functionality, using &#039;&#039;$filename&#039;&#039; as filename string in any reporting, deletes infected file if &#039;&#039;$deleteinfected&#039;&#039; is true.&lt;br /&gt;
&lt;br /&gt;
It is expected that &amp;lt;tt&amp;gt;scan_file()&amp;lt;/tt&amp;gt; function will throw exception of &amp;lt;tt&amp;gt;\core\antivirus\scanner_exception&amp;lt;/tt&amp;gt; type if virus is found, otherwise will return &#039;&#039;void&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The simplified example of scanner.php is shown below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// You must use the right namespace (matching your plugin antivirus name).&lt;br /&gt;
namespace antivirus_scanmyfile;&lt;br /&gt;
&lt;br /&gt;
defined(&#039;MOODLE_INTERNAL&#039;) || die();&lt;br /&gt;
&lt;br /&gt;
class scanner extends \core\antivirus\scanner {&lt;br /&gt;
&lt;br /&gt;
    public function is_configured() {&lt;br /&gt;
        // Parent&#039;s get_config() function is effectively a wrapper of get_config(&#039;antivirus_scanmyfile&#039;, &#039;somesettingname&#039;) call.&lt;br /&gt;
        return (bool)$this-&amp;gt;get_config(&#039;pathtoscanner&#039;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public function scan_file($file, $filename, $deleteinfected) {&lt;br /&gt;
        if (!is_readable($file)) {&lt;br /&gt;
            // This should not happen.&lt;br /&gt;
            debugging(&#039;File is not readable.&#039;);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Execute the scan using antivirus own scanning tool, we assume it returns 0 if no virus is found, 1 if file is infected, any other number on error.&lt;br /&gt;
        $return = $this-&amp;gt;scan_file_using_scanmyfile_scanner_tool($file);&lt;br /&gt;
&lt;br /&gt;
        if ($return == 0) {&lt;br /&gt;
            // Perfect, no problem found, file is clean.&lt;br /&gt;
            return;&lt;br /&gt;
        } else if ($return == 1) {&lt;br /&gt;
            // Infection found.&lt;br /&gt;
            if ($deleteinfected) {&lt;br /&gt;
                unlink($file);&lt;br /&gt;
            }&lt;br /&gt;
            throw new \core\antivirus\scanner_exception(&#039;virusfounduser&#039;, &#039;&#039;, array(&#039;filename&#039; =&amp;gt; $filename));&lt;br /&gt;
        } else {&lt;br /&gt;
            // Unknown problem.&lt;br /&gt;
            debugging(&#039;Error occurred during file scanning.&#039;);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public function scan_file_using_scanmyfile_scanner_tool($file) {&lt;br /&gt;
        // Scanning routine using antivirus own tool goes here.&lt;br /&gt;
        // ...&lt;br /&gt;
        // For example purposes, we assume it returns 0 if no virus is found, 1 if file is infected, any other number on error.&lt;br /&gt;
        return $return;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== tests/scanner_test.php (optional) ===&lt;br /&gt;
&lt;br /&gt;
Normally you would write a unit test for the antivirus plugin inside this file. Since plugin rely on external tool, it might be a good idea to replace real component with &amp;quot;double&amp;quot;. See ClamAV plugin for example and PHPUnit [https://phpunit.de/manual/current/en/test-doubles.html manual section].&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Antivirus_plugins&amp;diff=50253</id>
		<title>Antivirus plugins</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Antivirus_plugins&amp;diff=50253"/>
		<updated>2016-05-23T15:18:37Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: /* classes/scanner.php */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 3.1}}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
Antivirus plugins implement virus scanning functionality in Moodle. This allows external contributor to develop plugins for different antivirus products and extend existing antivirus functionality to different areas of Moodle. The plugin for ClamAV antivirus tool is included in the core.&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
&lt;br /&gt;
Antivirus scanning using ClamAV has been initially introduced in Moodle 1.3 in the [https://github.com/moodle/moodle/commit/18b8fbfa patchset] committed by Penny Leach. Since that time, the code has been refactored a number of times to match File and Repository API changes, however always remained limited to ClamAV antivirus product. In Moodle 3.1 antivirus scanning has been re-introduced as a separate plugin type with ClamAV plugin included in the core.&lt;br /&gt;
&lt;br /&gt;
== Current status ==&lt;br /&gt;
&lt;br /&gt;
The antivirus functionality is ongoing work, covered in MDL-50886. It most likely there will be some more API changes in upcoming release.&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
&lt;br /&gt;
The best example of antivirus plugin is ClamAV antivirus scanner plugin included in the core (&amp;lt;tt&amp;gt;/lib/antivirus/clamav&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
== File structure ==&lt;br /&gt;
&lt;br /&gt;
All files for an antivirus plugin go within &amp;lt;tt&amp;gt;/lib/antivirus/name&amp;lt;/tt&amp;gt;, where &amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt; is the name of the antivirus plugin, e.g. for ScanMyFile plugin used in examples below, the file structure will be as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 lib/antivirus/scanmyfile/&lt;br /&gt;
 |-- classes&lt;br /&gt;
 |   `-- scanner.php&lt;br /&gt;
 |-- db&lt;br /&gt;
 |   `-- upgrade.php&lt;br /&gt;
 |-- lang&lt;br /&gt;
 |   `-- en&lt;br /&gt;
 |       `-- antivirus_scanmyfile.php&lt;br /&gt;
 |-- settings.php&lt;br /&gt;
 |-- tests&lt;br /&gt;
 |   `-- scanner_test.php&lt;br /&gt;
 `-- version.php&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== version.php ===&lt;br /&gt;
&lt;br /&gt;
Standard [[version.php]] for the plugin.&lt;br /&gt;
&lt;br /&gt;
=== settings.php ===&lt;br /&gt;
&lt;br /&gt;
Standard [[Admin_settings]] for the plugin configuration, make sure plugin configuration is stored in &amp;lt;tt&amp;gt;config_plugins&amp;lt;/tt&amp;gt; table.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if ($ADMIN-&amp;gt;fulltree) {&lt;br /&gt;
    $settings-&amp;gt;add(new admin_setting_configexecutable(&#039;antivirus_scanmyfile/pathtoscanner&#039;,&lt;br /&gt;
            new lang_string(&#039;pathtoscanner&#039;, &#039;antivirus_scanmyfile&#039;), new lang_string(&#039;configpathtoscanner&#039;, &#039;antivirus_scanmyfile&#039;), &#039;&#039;));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== lang/en/antivirus_scanmyfile.php ===&lt;br /&gt;
&lt;br /&gt;
Language strings for the plugin. Required strings:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;pluginname&#039;&#039;&#039; - name of plugin.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$string[&#039;pluginname&#039;] = &#039;SanMyFile antivirus&#039;;&lt;br /&gt;
$string[&#039;pathtoscanner&#039;] = &#039;Path to scanner&#039;;&lt;br /&gt;
$string[&#039;configpathtoscanner&#039;] = &#039;Define full path to scanner&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will usually need to add your own strings for two main purposes:&lt;br /&gt;
&lt;br /&gt;
* Adding configuration settings.&lt;br /&gt;
* Displaying information about scanning errors.&lt;br /&gt;
&lt;br /&gt;
=== db (directory) ===&lt;br /&gt;
&lt;br /&gt;
Standard upgrade/install routines for plugin.&lt;br /&gt;
&lt;br /&gt;
=== classes/scanner.php ===&lt;br /&gt;
&lt;br /&gt;
The file contains &amp;lt;tt&amp;gt;scanner&amp;lt;/tt&amp;gt; class defined in &amp;lt;tt&amp;gt;antivirus_name&amp;lt;/tt&amp;gt; namespace, that extends &amp;lt;tt&amp;gt;\core\antivirus\scanner&amp;lt;/tt&amp;gt; class and implements the back-end for the antivirus scanning. It is expected that the class will contain at least two methods:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt&amp;gt;is_configured()&amp;lt;/tt&amp;gt; - returns true, if this antivirus plugin is configured.&lt;br /&gt;
* &amp;lt;tt&amp;gt;scan_file($file, $filename, $deleteinfected)&amp;lt;/tt&amp;gt; - performs the &#039;&#039;$file&#039;&#039; scanning using antivirus functionality, using &#039;&#039;$filename&#039;&#039; as filename string in any reporting, deletes infected file if &#039;&#039;$deleteinfected&#039;&#039; is true.&lt;br /&gt;
&lt;br /&gt;
It is expected that &amp;lt;tt&amp;gt;scan_file()&amp;lt;/tt&amp;gt; function will throw exception of &amp;lt;tt&amp;gt;\core\antivirus\scanner_exception&amp;lt;/tt&amp;gt; type if virus is found, otherwise will return &#039;&#039;void&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The simplified example of scanner.php is shown below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// You must use the right namespace (matching your plugin antivirus name).&lt;br /&gt;
namespace antivirus_scanmyfile;&lt;br /&gt;
&lt;br /&gt;
defined(&#039;MOODLE_INTERNAL&#039;) || die();&lt;br /&gt;
&lt;br /&gt;
class scanner extends \core\antivirus\scanner {&lt;br /&gt;
&lt;br /&gt;
    public function is_configured() {&lt;br /&gt;
        // Parent&#039;s get_config() function is effectively a wrapper of get_config(&#039;antivirus_scanmyfile&#039;, &#039;somesettingname&#039;) call.&lt;br /&gt;
        return (bool)$this-&amp;gt;get_config(&#039;pathtoscanner&#039;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public function scan_file($file, $filename, $deleteinfected) {&lt;br /&gt;
        if (!is_readable($file)) {&lt;br /&gt;
            // This should not happen.&lt;br /&gt;
            debugging(&#039;File is not readable.&#039;);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Execute the scan using antivirus own scanning tool, we assume it returns 0 if no virus is found, 1 if file is infected, any other number on error.&lt;br /&gt;
        $return = scan_file_using_scanmyfile_scanner_tool($file);&lt;br /&gt;
&lt;br /&gt;
        if ($return == 0) {&lt;br /&gt;
            // Perfect, no problem found, file is clean.&lt;br /&gt;
            return;&lt;br /&gt;
        } else if ($return == 1) {&lt;br /&gt;
            // Infection found.&lt;br /&gt;
            if ($deleteinfected) {&lt;br /&gt;
                unlink($file);&lt;br /&gt;
            }&lt;br /&gt;
            throw new \core\antivirus\scanner_exception(&#039;virusfounduser&#039;, &#039;&#039;, array(&#039;filename&#039; =&amp;gt; $filename));&lt;br /&gt;
        } else {&lt;br /&gt;
            // Unknown problem.&lt;br /&gt;
            debugging(&#039;Error occurred during file scanning.&#039;);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    scan_file_using_scanmyfile_scanner_tool($file) {&lt;br /&gt;
        // Scanning routine using antivirus own tool goes here.&lt;br /&gt;
        // ...&lt;br /&gt;
        // For example purposes, we assume it returns 0 if no virus is found, 1 if file is infected, any other number on error.&lt;br /&gt;
        return $return;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== tests/scanner_test.php (optional) ===&lt;br /&gt;
&lt;br /&gt;
Normally you would write a unit test for the antivirus plugin inside this file. Since plugin rely on external tool, it might be a good idea to replace real component with &amp;quot;double&amp;quot;. See ClamAV plugin for example and PHPUnit [https://phpunit.de/manual/current/en/test-doubles.html manual section].&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Antivirus_plugins&amp;diff=50252</id>
		<title>Antivirus plugins</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Antivirus_plugins&amp;diff=50252"/>
		<updated>2016-05-23T15:14:45Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: /* lang/en/antivirus_scanmyfile.php */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 3.1}}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
Antivirus plugins implement virus scanning functionality in Moodle. This allows external contributor to develop plugins for different antivirus products and extend existing antivirus functionality to different areas of Moodle. The plugin for ClamAV antivirus tool is included in the core.&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
&lt;br /&gt;
Antivirus scanning using ClamAV has been initially introduced in Moodle 1.3 in the [https://github.com/moodle/moodle/commit/18b8fbfa patchset] committed by Penny Leach. Since that time, the code has been refactored a number of times to match File and Repository API changes, however always remained limited to ClamAV antivirus product. In Moodle 3.1 antivirus scanning has been re-introduced as a separate plugin type with ClamAV plugin included in the core.&lt;br /&gt;
&lt;br /&gt;
== Current status ==&lt;br /&gt;
&lt;br /&gt;
The antivirus functionality is ongoing work, covered in MDL-50886. It most likely there will be some more API changes in upcoming release.&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
&lt;br /&gt;
The best example of antivirus plugin is ClamAV antivirus scanner plugin included in the core (&amp;lt;tt&amp;gt;/lib/antivirus/clamav&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
== File structure ==&lt;br /&gt;
&lt;br /&gt;
All files for an antivirus plugin go within &amp;lt;tt&amp;gt;/lib/antivirus/name&amp;lt;/tt&amp;gt;, where &amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt; is the name of the antivirus plugin, e.g. for ScanMyFile plugin used in examples below, the file structure will be as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 lib/antivirus/scanmyfile/&lt;br /&gt;
 |-- classes&lt;br /&gt;
 |   `-- scanner.php&lt;br /&gt;
 |-- db&lt;br /&gt;
 |   `-- upgrade.php&lt;br /&gt;
 |-- lang&lt;br /&gt;
 |   `-- en&lt;br /&gt;
 |       `-- antivirus_scanmyfile.php&lt;br /&gt;
 |-- settings.php&lt;br /&gt;
 |-- tests&lt;br /&gt;
 |   `-- scanner_test.php&lt;br /&gt;
 `-- version.php&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== version.php ===&lt;br /&gt;
&lt;br /&gt;
Standard [[version.php]] for the plugin.&lt;br /&gt;
&lt;br /&gt;
=== settings.php ===&lt;br /&gt;
&lt;br /&gt;
Standard [[Admin_settings]] for the plugin configuration, make sure plugin configuration is stored in &amp;lt;tt&amp;gt;config_plugins&amp;lt;/tt&amp;gt; table.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if ($ADMIN-&amp;gt;fulltree) {&lt;br /&gt;
    $settings-&amp;gt;add(new admin_setting_configexecutable(&#039;antivirus_scanmyfile/pathtoscanner&#039;,&lt;br /&gt;
            new lang_string(&#039;pathtoscanner&#039;, &#039;antivirus_scanmyfile&#039;), new lang_string(&#039;configpathtoscanner&#039;, &#039;antivirus_scanmyfile&#039;), &#039;&#039;));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== lang/en/antivirus_scanmyfile.php ===&lt;br /&gt;
&lt;br /&gt;
Language strings for the plugin. Required strings:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;pluginname&#039;&#039;&#039; - name of plugin.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$string[&#039;pluginname&#039;] = &#039;SanMyFile antivirus&#039;;&lt;br /&gt;
$string[&#039;pathtoscanner&#039;] = &#039;Path to scanner&#039;;&lt;br /&gt;
$string[&#039;configpathtoscanner&#039;] = &#039;Define full path to scanner&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will usually need to add your own strings for two main purposes:&lt;br /&gt;
&lt;br /&gt;
* Adding configuration settings.&lt;br /&gt;
* Displaying information about scanning errors.&lt;br /&gt;
&lt;br /&gt;
=== db (directory) ===&lt;br /&gt;
&lt;br /&gt;
Standard upgrade/install routines for plugin.&lt;br /&gt;
&lt;br /&gt;
=== classes/scanner.php ===&lt;br /&gt;
&lt;br /&gt;
The file contains &amp;lt;tt&amp;gt;scanner&amp;lt;/tt&amp;gt; class defined in &amp;lt;tt&amp;gt;antivirus_name&amp;lt;/tt&amp;gt; namespace, that extends &amp;lt;tt&amp;gt;\core\antivirus\scanner&amp;lt;/tt&amp;gt; class and implements the back-end for the antivirus scanning. It is expected that the class will contain at least two methods:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt&amp;gt;is_configured()&amp;lt;/tt&amp;gt; - returns true, if this antivirus plugin is configured.&lt;br /&gt;
* &amp;lt;tt&amp;gt;scan_file($file, $filename, $deleteinfected)&amp;lt;/tt&amp;gt; - performs the &#039;&#039;$file&#039;&#039; scanning using antivirus functionality, using &#039;&#039;$filename&#039;&#039; as filename string in any reporting, deletes infected file if &#039;&#039;$deleteinfected&#039;&#039; is true.&lt;br /&gt;
&lt;br /&gt;
It is expected that &amp;lt;tt&amp;gt;scan_file()&amp;lt;/tt&amp;gt; function will throw exception of &amp;lt;tt&amp;gt;\core\antivirus\scanner_exception&amp;lt;/tt&amp;gt; type if virus is found, otherwise will return &#039;&#039;void&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The simplified example of scanner.php is shown below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// You must use the right namespace (matching your plugin antivirus name).&lt;br /&gt;
namespace antivirus_scanmyfile;&lt;br /&gt;
&lt;br /&gt;
defined(&#039;MOODLE_INTERNAL&#039;) || die();&lt;br /&gt;
&lt;br /&gt;
class scanner extends \core\antivirus\scanner {&lt;br /&gt;
&lt;br /&gt;
    public function is_configured() {&lt;br /&gt;
        // Parent&#039;s get_config() function is effectively a wrapper of get_config(&#039;antivirus_scanmyfile&#039;, &#039;somesettingname&#039;) call.&lt;br /&gt;
        return (bool)$this-&amp;gt;get_config(&#039;pathtoscanner&#039;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public function scan_file($file, $filename, $deleteinfected) {&lt;br /&gt;
        if (!is_readable($file)) {&lt;br /&gt;
            // This should not happen.&lt;br /&gt;
            debugging(&#039;File is not readable.&#039;);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Execute the scan using antivirus own scanning tool, we assume it returns 0 if no virus is found, 1 if file is infected, any other number on error.&lt;br /&gt;
        $return = scan_file_using_scanmyfile_scanner_tool($file);&lt;br /&gt;
&lt;br /&gt;
        if ($return == 0) {&lt;br /&gt;
            // Perfect, no problem found, file is clean.&lt;br /&gt;
            return;&lt;br /&gt;
        } else if ($return == 1) {&lt;br /&gt;
            // Infection found.&lt;br /&gt;
            if ($deleteinfected) {&lt;br /&gt;
                unlink($file);&lt;br /&gt;
            }&lt;br /&gt;
            throw new \core\antivirus\scanner_exception(&#039;virusfounduser&#039;, &#039;&#039;, array(&#039;filename&#039; =&amp;gt; $filename));&lt;br /&gt;
        } else {&lt;br /&gt;
            // Unknown problem.&lt;br /&gt;
            debugging(&#039;Error occurred during file scanning.&#039;);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== tests/scanner_test.php (optional) ===&lt;br /&gt;
&lt;br /&gt;
Normally you would write a unit test for the antivirus plugin inside this file. Since plugin rely on external tool, it might be a good idea to replace real component with &amp;quot;double&amp;quot;. See ClamAV plugin for example and PHPUnit [https://phpunit.de/manual/current/en/test-doubles.html manual section].&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Antivirus_plugins&amp;diff=50251</id>
		<title>Antivirus plugins</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Antivirus_plugins&amp;diff=50251"/>
		<updated>2016-05-23T15:13:39Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: Created page with &amp;quot;{{Moodle 3.1}}  == Introduction ==  Antivirus plugins implement virus scanning functionality in Moodle. This allows external contributor to develop plugins for different antiv...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 3.1}}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
Antivirus plugins implement virus scanning functionality in Moodle. This allows external contributor to develop plugins for different antivirus products and extend existing antivirus functionality to different areas of Moodle. The plugin for ClamAV antivirus tool is included in the core.&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
&lt;br /&gt;
Antivirus scanning using ClamAV has been initially introduced in Moodle 1.3 in the [https://github.com/moodle/moodle/commit/18b8fbfa patchset] committed by Penny Leach. Since that time, the code has been refactored a number of times to match File and Repository API changes, however always remained limited to ClamAV antivirus product. In Moodle 3.1 antivirus scanning has been re-introduced as a separate plugin type with ClamAV plugin included in the core.&lt;br /&gt;
&lt;br /&gt;
== Current status ==&lt;br /&gt;
&lt;br /&gt;
The antivirus functionality is ongoing work, covered in MDL-50886. It most likely there will be some more API changes in upcoming release.&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
&lt;br /&gt;
The best example of antivirus plugin is ClamAV antivirus scanner plugin included in the core (&amp;lt;tt&amp;gt;/lib/antivirus/clamav&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
== File structure ==&lt;br /&gt;
&lt;br /&gt;
All files for an antivirus plugin go within &amp;lt;tt&amp;gt;/lib/antivirus/name&amp;lt;/tt&amp;gt;, where &amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt; is the name of the antivirus plugin, e.g. for ScanMyFile plugin used in examples below, the file structure will be as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 lib/antivirus/scanmyfile/&lt;br /&gt;
 |-- classes&lt;br /&gt;
 |   `-- scanner.php&lt;br /&gt;
 |-- db&lt;br /&gt;
 |   `-- upgrade.php&lt;br /&gt;
 |-- lang&lt;br /&gt;
 |   `-- en&lt;br /&gt;
 |       `-- antivirus_scanmyfile.php&lt;br /&gt;
 |-- settings.php&lt;br /&gt;
 |-- tests&lt;br /&gt;
 |   `-- scanner_test.php&lt;br /&gt;
 `-- version.php&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== version.php ===&lt;br /&gt;
&lt;br /&gt;
Standard [[version.php]] for the plugin.&lt;br /&gt;
&lt;br /&gt;
=== settings.php ===&lt;br /&gt;
&lt;br /&gt;
Standard [[Admin_settings]] for the plugin configuration, make sure plugin configuration is stored in &amp;lt;tt&amp;gt;config_plugins&amp;lt;/tt&amp;gt; table.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if ($ADMIN-&amp;gt;fulltree) {&lt;br /&gt;
    $settings-&amp;gt;add(new admin_setting_configexecutable(&#039;antivirus_scanmyfile/pathtoscanner&#039;,&lt;br /&gt;
            new lang_string(&#039;pathtoscanner&#039;, &#039;antivirus_scanmyfile&#039;), new lang_string(&#039;configpathtoscanner&#039;, &#039;antivirus_scanmyfile&#039;), &#039;&#039;));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== lang/en/antivirus_scanmyfile.php ===&lt;br /&gt;
&lt;br /&gt;
Language strings for the plugin. Required strings:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;pluginname&#039;&#039;&#039; - name of plugin.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$string[&#039;pluginname&#039;] = &#039;ClamAV antivirus&#039;;&lt;br /&gt;
$string[&#039;pathtoscanner&#039;] = &#039;Path to scanner&#039;;&lt;br /&gt;
$string[&#039;configpathtoscanner&#039;] = &#039;Define full path to scanner&#039;;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will usually need to add your own strings for two main purposes:&lt;br /&gt;
&lt;br /&gt;
* Adding configuration settings.&lt;br /&gt;
* Displaying information about scanning errors.&lt;br /&gt;
&lt;br /&gt;
=== db (directory) ===&lt;br /&gt;
&lt;br /&gt;
Standard upgrade/install routines for plugin.&lt;br /&gt;
&lt;br /&gt;
=== classes/scanner.php ===&lt;br /&gt;
&lt;br /&gt;
The file contains &amp;lt;tt&amp;gt;scanner&amp;lt;/tt&amp;gt; class defined in &amp;lt;tt&amp;gt;antivirus_name&amp;lt;/tt&amp;gt; namespace, that extends &amp;lt;tt&amp;gt;\core\antivirus\scanner&amp;lt;/tt&amp;gt; class and implements the back-end for the antivirus scanning. It is expected that the class will contain at least two methods:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tt&amp;gt;is_configured()&amp;lt;/tt&amp;gt; - returns true, if this antivirus plugin is configured.&lt;br /&gt;
* &amp;lt;tt&amp;gt;scan_file($file, $filename, $deleteinfected)&amp;lt;/tt&amp;gt; - performs the &#039;&#039;$file&#039;&#039; scanning using antivirus functionality, using &#039;&#039;$filename&#039;&#039; as filename string in any reporting, deletes infected file if &#039;&#039;$deleteinfected&#039;&#039; is true.&lt;br /&gt;
&lt;br /&gt;
It is expected that &amp;lt;tt&amp;gt;scan_file()&amp;lt;/tt&amp;gt; function will throw exception of &amp;lt;tt&amp;gt;\core\antivirus\scanner_exception&amp;lt;/tt&amp;gt; type if virus is found, otherwise will return &#039;&#039;void&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The simplified example of scanner.php is shown below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
// You must use the right namespace (matching your plugin antivirus name).&lt;br /&gt;
namespace antivirus_scanmyfile;&lt;br /&gt;
&lt;br /&gt;
defined(&#039;MOODLE_INTERNAL&#039;) || die();&lt;br /&gt;
&lt;br /&gt;
class scanner extends \core\antivirus\scanner {&lt;br /&gt;
&lt;br /&gt;
    public function is_configured() {&lt;br /&gt;
        // Parent&#039;s get_config() function is effectively a wrapper of get_config(&#039;antivirus_scanmyfile&#039;, &#039;somesettingname&#039;) call.&lt;br /&gt;
        return (bool)$this-&amp;gt;get_config(&#039;pathtoscanner&#039;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public function scan_file($file, $filename, $deleteinfected) {&lt;br /&gt;
        if (!is_readable($file)) {&lt;br /&gt;
            // This should not happen.&lt;br /&gt;
            debugging(&#039;File is not readable.&#039;);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Execute the scan using antivirus own scanning tool, we assume it returns 0 if no virus is found, 1 if file is infected, any other number on error.&lt;br /&gt;
        $return = scan_file_using_scanmyfile_scanner_tool($file);&lt;br /&gt;
&lt;br /&gt;
        if ($return == 0) {&lt;br /&gt;
            // Perfect, no problem found, file is clean.&lt;br /&gt;
            return;&lt;br /&gt;
        } else if ($return == 1) {&lt;br /&gt;
            // Infection found.&lt;br /&gt;
            if ($deleteinfected) {&lt;br /&gt;
                unlink($file);&lt;br /&gt;
            }&lt;br /&gt;
            throw new \core\antivirus\scanner_exception(&#039;virusfounduser&#039;, &#039;&#039;, array(&#039;filename&#039; =&amp;gt; $filename));&lt;br /&gt;
        } else {&lt;br /&gt;
            // Unknown problem.&lt;br /&gt;
            debugging(&#039;Error occurred during file scanning.&#039;);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== tests/scanner_test.php (optional) ===&lt;br /&gt;
&lt;br /&gt;
Normally you would write a unit test for the antivirus plugin inside this file. Since plugin rely on external tool, it might be a good idea to replace real component with &amp;quot;double&amp;quot;. See ClamAV plugin for example and PHPUnit [https://phpunit.de/manual/current/en/test-doubles.html manual section].&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Deprecation&amp;diff=47503</id>
		<title>Deprecation</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Deprecation&amp;diff=47503"/>
		<updated>2015-03-12T15:59:59Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: /* Step 1. Immediate action */ Fix Coding style deprecated section link.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What is deprecation? ==&lt;br /&gt;
&lt;br /&gt;
[http://en.wikipedia.org/wiki/Deprecation Deprecation], in its programming sense, is the process of taking older code and marking it as no longer being useful within the codebase, usually because it has been superseded by newer code. The deprecated code is not immediately removed from the codebase because doing so may cause regression errors.&lt;br /&gt;
&lt;br /&gt;
== Why is deprecation needed? ==&lt;br /&gt;
&lt;br /&gt;
In an open source project, the end use of the codebase varies. People may have customisations and plugins that depend on a function that has been targeted for deprecation. Rather than simply removing a function, we must gracefully deprecate the function over a period covered by a number of released versions.&lt;br /&gt;
&lt;br /&gt;
== Moodle Core deprecation process ==&lt;br /&gt;
&lt;br /&gt;
Once it is decided that a function should be deprecated, a two-step process should be followed.&lt;br /&gt;
&lt;br /&gt;
Note that both steps should always happen as earlier as possible in the 6-months period  between major releases, so all developers will have time to adjust their code and ensure it will work in the next release. Obviously, no changes will be allowed after code freeze (the APIs must remain 100% unmodified after it).&lt;br /&gt;
&lt;br /&gt;
Every deprecation should be documented in the corresponding upgrade.txt files &#039;&#039;&#039;at least&#039;&#039;&#039; once, but ideally both on initial deprecation and on final removal.&lt;br /&gt;
&lt;br /&gt;
=== Step 1. Immediate action ===&lt;br /&gt;
&lt;br /&gt;
Deprecation affects only the current master version, in other words, the deprecation only becomes affective after the next [[Releases|major release]].&lt;br /&gt;
&lt;br /&gt;
* If the function is not a member of a class (in other words, it is an independent function), it should be moved, with its PHPDoc and all comments, to &#039;&#039;lib/deprecationlib.php&#039;&#039;, which is included everywhere. If the function is a class member, it will need to be deprecated in its current location.&lt;br /&gt;
** Deprecated behat step definitions should be moved to lib/tests/behat/behat_deprecated.php, including a call to behat_deprecated::deprecated_message() proposing an alternative to the deprecated method.&lt;br /&gt;
* A debugging message should be added to the function so that, when [[:en:Debugging|developer debugging mode]] is on, attention is drawn to the deprecation. The message should state that the function being called has been deprecated. If the function has been replaced, the user should be directed to the alternative.&lt;br /&gt;
&lt;br /&gt;
 debugging(&#039;foobar() is deprecated, please use foobar::blah() instead.&#039;, DEBUG_DEVELOPER);&lt;br /&gt;
&lt;br /&gt;
* If the deprecated function has been replaced with a new function, ideally the new function should be called from the deprecated function, so that the new functionality is used. This will make maintenance easier moving forward.&lt;br /&gt;
* A &amp;lt;tt&amp;gt;@deprecated&amp;lt;/tt&amp;gt; tag should be added to the PHPDoc for the function description so that IDEs describing the function will note that it is deprecated, documenting which version it was deprecated in and the MDL issue associated with it. See the guidelines in [[Coding_style#.40deprecated_.28and_.40todo.29]].&lt;br /&gt;
* There will need to be an issue associated with the initial part of the deprecation. A second issue needs to be created to finish the job. The first issue will be linked to second issue. The second issue needs to be a sub-task of an appropriate [http://tracker.moodle.org/secure/IssueNavigator!executeAdvanced.jspa?jqlQuery=summary+%7E+%22meta+AND+deprecation%22+order+by+created&amp;amp;runQuery=true&amp;amp;clear=true deprecation META]. For example, if the current version is 2.3.2, the function will be marked as deprecated in 2.4 and should normally be removed for 2.6, so the second issue should be a subtask of a deprecation META for the 2.6 version (MDL-34434). This second issue should include instructions on how to remove the function so that when it comes time to do so, the task is trivial for any developer.&lt;br /&gt;
* A &amp;lt;tt&amp;gt;@todo&amp;lt;/tt&amp;gt; tag can be added linking to the issues created for further action. (optional)&lt;br /&gt;
* A &amp;lt;tt&amp;gt;@see&amp;lt;/tt&amp;gt; tag can be added to point to the new apis that can be used. (optional)&lt;br /&gt;
&lt;br /&gt;
Longer deprecation periods can be considered for functions that are widely used.&lt;br /&gt;
&lt;br /&gt;
=== Step 2. Final deprecation ===&lt;br /&gt;
&lt;br /&gt;
* If a function has been marked as deprecated for 2.x (eg. 2.4) and set for removal at 2.x+2 (eg. 2.6), soon after the release of 2.x+1.1 (eg. 2.5.1), the 2.x+2 deprecation META will be processed. This means that the deprecated function will be removed before 2.x+2, but only in the master version. This allows any potential regressions caused by the removal of the function to be exposed as soon as possible.&lt;br /&gt;
* All content of the function is removed and in the skeleton that remains,  an error statement should be included that reports that the function has been removed. You can direct developers to new function(s) in this message.&lt;br /&gt;
&lt;br /&gt;
 throw new coding_exception(&#039;check_potential_filename() can not be used any more, please use new file API&#039;);&lt;br /&gt;
&lt;br /&gt;
* The PHPDoc for the function should have &amp;lt;tt&amp;gt;@param&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;@return&amp;lt;/tt&amp;gt; tags removed to reduce the temptation for developers to consider using the function and make it obvious in IDEs that the function has been deprecated. The &amp;lt;tt&amp;gt;@deprecated&amp;lt;/tt&amp;gt; tag should remain. When feasible the description should be removed as well, &#039;&#039;&#039;but do not remove the information about what you should use instead of the deprecated function&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== See also... ==&lt;br /&gt;
&lt;br /&gt;
* [[Process]]&lt;br /&gt;
* [[Release process]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Processes]]&lt;br /&gt;
[[Category:Core development]]&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=47490</id>
		<title>HTML5 player</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=47490"/>
		<updated>2015-03-10T13:36:41Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: /* Comparison Matrix */ Fix colspan for section fields.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}&lt;br /&gt;
{{Infobox Project&lt;br /&gt;
|name = HTML5 Player with flash fallback&lt;br /&gt;
|state = In Development&lt;br /&gt;
|tracker = https://tracker.moodle.org/browse/MDL-38158&lt;br /&gt;
|discussion = https://moodle.org/mod/forum/discuss.php?d=222753#p1110024&lt;br /&gt;
|assignee = [https://tracker.moodle.org/secure/ViewProfile.jspa?name=kabalin Ruslan Kabalin]&lt;br /&gt;
}}&lt;br /&gt;
{{Moodle 2.x}}&lt;br /&gt;
&lt;br /&gt;
== Project goals ==&lt;br /&gt;
&lt;br /&gt;
The purpose of this document is to choose HTML5 player with flash fallback for integration in Moodle and plan its implementation.&lt;br /&gt;
&lt;br /&gt;
The aim of this change is to reach a consistent look of the player among different platforms and browsers, as well as making sure that player starts using flash if html5 is not supported by browser for the given format. Another aim is to improve accessibility and usability, enhance customisation.&lt;br /&gt;
&lt;br /&gt;
== Considerations ==&lt;br /&gt;
&lt;br /&gt;
* Usability of the player - is it easy to use it and intuitively understand how to use controls?&lt;br /&gt;
* Accessibility of the player - possibility of keyboard navigation, subtitles, support?&lt;br /&gt;
* Appearance of the player - can its interface be modified, themes support, RTL?&lt;br /&gt;
* Consistency among browsers - does player look the same?&lt;br /&gt;
* Audio support - can player handle HTML5 &amp;lt;audio&amp;gt; tag?&lt;br /&gt;
* Mobile platforms support - does player also work on iOS and Android?&lt;br /&gt;
* Streaming media support (including adaptive-bitrate delivery) - can player handle RTMP, Apple HLS, Adobe HDS, Microsoft HSS?&lt;br /&gt;
* Plugins support - can we use or develop community plugins easily?&lt;br /&gt;
* Embedding support - so users could post media content outside Moodle, if permitted.&lt;br /&gt;
* Maintainability of the links between the player and Moodle - how much work will we need to do every time we upgrade?&lt;br /&gt;
&lt;br /&gt;
== Candidates ==&lt;br /&gt;
&lt;br /&gt;
* [http://flowplayer.org/ Flowplayer HTML5]&lt;br /&gt;
* [http://www.videojs.com/ Video.JS]&lt;br /&gt;
* [http://www.projekktor.com/ Projekktor]&lt;br /&gt;
* [http://mediaelementjs.com/ MediaElement.js]&lt;br /&gt;
* ?Are there other alternatives?&lt;br /&gt;
&lt;br /&gt;
== Comparison Matrix ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! [[#Flowplayer_HTML5|Flowplayer HTML5]]&lt;br /&gt;
! [[#Video.JS|Video.JS]]&lt;br /&gt;
! [[#Projekktor|Projekktor]]&lt;br /&gt;
! [[#MediaElement.js|MediaElement.js]]&lt;br /&gt;
! No Player&lt;br /&gt;
|-&lt;br /&gt;
! Accessible Player:&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Keyboard control&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes (configurable)&lt;br /&gt;
| Yes&lt;br /&gt;
| unknown&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Subtitles support&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via plugin)&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (see http://caniuse.com/webvtt)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Touch interface&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Appearance:&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Skins&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* CSS customisation&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| unknown&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTL support&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| No&lt;br /&gt;
| Unknown (CSS, so I guess so...)&lt;br /&gt;
| Unknown&lt;br /&gt;
|-&lt;br /&gt;
! Mobile platforms:&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* iOS&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Android&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Streaming protocols:&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTMP&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via playlist)&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Adaptive HTTP&lt;br /&gt;
| HLS&lt;br /&gt;
| HLS (via plugin)&lt;br /&gt;
| HLS (via playlist)&lt;br /&gt;
| HLS&lt;br /&gt;
| Only in Chrome so far (Media Source Extension)&lt;br /&gt;
|-&lt;br /&gt;
! Audio player&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Embedding support&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (configurable)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via addThis plugin)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via plugin)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | No&lt;br /&gt;
|-&lt;br /&gt;
! License&lt;br /&gt;
| GPL v3 (with additional terms)&lt;br /&gt;
| Apache 2&lt;br /&gt;
| GPL v3&lt;br /&gt;
| MIT&lt;br /&gt;
| no extra code needed&lt;br /&gt;
|-&lt;br /&gt;
! JS library&lt;br /&gt;
| jQuery&lt;br /&gt;
| -&lt;br /&gt;
| jQuery&lt;br /&gt;
| jQuery&lt;br /&gt;
| none required&lt;br /&gt;
|-&lt;br /&gt;
! Plugins infrastructure&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
! Flash fallback player&lt;br /&gt;
| Flowplayer Flash&lt;br /&gt;
| video-js flash&lt;br /&gt;
| StobeMediaPlayback (but can be jarisplayer or some other).&lt;br /&gt;
| Flash and Silverlight (for .wmv support) fallback, used to provide the HTML5 video/audio elements.&lt;br /&gt;
| The Video tag can contain fallback content (e.g. Flash object) for browsers that don&#039;t support it at all (http://camendesign.com/code/video_for_everybody), but not based on codec support.&lt;br /&gt;
|-&lt;br /&gt;
! API&lt;br /&gt;
| Yes (plus window.flowplayer object)&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Flowplayer HTML5 ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* Good looking player, resembles existing flash flowplayer in Moodle (with &amp;quot;functional&amp;quot; skin)&lt;br /&gt;
* Extensive customisation (via CSS3 skins and configuration object)&lt;br /&gt;
* Streaming support (RTMP, HLS)&lt;br /&gt;
* Good accessibility features&lt;br /&gt;
* Configurable embedding functionality&lt;br /&gt;
* Existing flash flowplayer can be configured for fallback (the appearance of player will not be affected).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Require jQuery for functioning&lt;br /&gt;
* Flowplayer logo remains on screen&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using wrapper around &amp;lt;video&amp;gt;.&lt;br /&gt;
* width and height attributes in video tag are ignored, player size is configured via wrapper size only.&lt;br /&gt;
* RTMP server connection is configured via data-rtmp attribute in wrapper or player init config parameter, actual path the file specified in src attribute of source item.&lt;br /&gt;
* &amp;lt;source type=&amp;quot;video/flash&amp;quot;... dummy MIME type to force using plash player for whatever content.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Plugins infrastructure&lt;br /&gt;
* No audio support&lt;br /&gt;
&lt;br /&gt;
=== Video.JS ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Extensive API.&lt;br /&gt;
* No extra JS library needed.&lt;br /&gt;
* Many plugins.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Poor documentation&lt;br /&gt;
* RTMP requires non-standard MIME.&lt;br /&gt;
* Android and iOS override Video.JS with own player, when not overridden, content is not playing.&lt;br /&gt;
* No RTL.&lt;br /&gt;
* HLS support via plugin (many files to include, external contributor see https://github.com/videojs/videojs-contrib-hls).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* RTMP server connection and path specified as single URI in src attribute of source item, &#039;&amp;amp;&#039; character is used as server connection and path divider.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Embedded HLS support.&lt;br /&gt;
&lt;br /&gt;
=== MediaElement.js ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* Flash fall-forward - uses Flash/Silverlight to provide the HTML5 MediaElement API.&lt;br /&gt;
* Consistent HTML/CSS Player&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* ...&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* ...&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* ...&lt;br /&gt;
&lt;br /&gt;
=== Projekktor ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Well documented API.&lt;br /&gt;
* Media RSS support.&lt;br /&gt;
* Possibility to choose flash player for fallback (included by default are StrobeMediaPlayback and Jarisplayer, both Open Source).&lt;br /&gt;
* Platform preference order selection (e.g. browser, ios, android, flash, native).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Uses flash where it is not supposed to (e.g. mp4 in Chrome).&lt;br /&gt;
* Issues on ios and android (suggests to download file when play button is pressed).&lt;br /&gt;
* RTMP only work if defined via playlist rather than in &amp;lt;source&amp;gt; tags.&lt;br /&gt;
* Subtitles plugin is not free.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* Make sure &amp;lt;video&amp;gt; tag has class attribute with &#039;projekktor&#039; value (even if you initialise it by ID of the element), player will not work properly otherwise.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== HTML5 browser native ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* Simple&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* IE8 has no support&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes&#039;&#039;&#039;&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Cross-browser support ==&lt;br /&gt;
&lt;br /&gt;
=== Method ===&lt;br /&gt;
Compatibility checks were done manually by accessing the sample page using different browsers and platforms. Sample page contained the list of identical player instances, initialised for each &amp;lt;video&amp;gt; definition with a &amp;lt;source&amp;gt; of particular format: mp4, webm, ogg, flv. Streaming support was checked by setting up a &amp;lt;video&amp;gt; container with two sources of the same video, one was HLS (Apple HTTP Live Streaming) stream for browsers and platforms that support html5 video streaming, another one was RTMP which is played using flash engine and supposed to be used in case if HLS is not supported.&lt;br /&gt;
&lt;br /&gt;
=== Sample Pages ===&lt;br /&gt;
&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=flowplayer Flowplayer HTML5] version 5.4.6.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=videojs Video.JS] version 4.4.1.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=projekktor Projekktor] version 1.3.09.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=mediaelementjs MediaElement.js] version 2.6.14&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=native Native browser support].&lt;br /&gt;
&lt;br /&gt;
=== Source ===&lt;br /&gt;
&lt;br /&gt;
Source of testing page is hosted on [https://github.com/kabalin/test-html5-players/blob/master/players.php github]. The actual source of the html page can be viewed in browser.&lt;br /&gt;
&lt;br /&gt;
=== Discussion ===&lt;br /&gt;
&lt;br /&gt;
The players comparison that has been carried out demonstrated that &amp;quot;least hassle&amp;quot; player is Flowplayer. Despite some drawbacks listed in [[#Flowplayer_HTML5|corresponding section above]], it is clearly a winner as it works as expected and according to documentation for all browsers and platforms I had chance to test it. This is the only player that supports RTL layout, display platform incompatibility message prior to attempt to play, and was simple to configure (no undocumented tricks that I had to figure out to make it work). Both VideoJS and Projekktor do now perform properly in all cases. Among those two, I personally prefer Projekktor more for its extensive API, plugins infrastructure and configuration flexibility. However problems on mobile platforms and flash fallback inconsistency make them unreliable at this stage.&lt;br /&gt;
&lt;br /&gt;
=== Compatibility results ===&lt;br /&gt;
&lt;br /&gt;
The table was populated using Flowplayer as others do not perform good enough with some formats and platforms, e.g. VideoJS allow mobile platform player to override itself, Projekktor does not always use HTML5 where browser clearly can handle it (supported in native mode and Flowplayer).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Browser&lt;br /&gt;
! mp4&lt;br /&gt;
! webm&lt;br /&gt;
! ogg&lt;br /&gt;
! flv&lt;br /&gt;
! RTMP/HLS*&lt;br /&gt;
|-&lt;br /&gt;
! Windows 7&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Firefox 27.0.1&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 12.16&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 5.1.7&lt;br /&gt;
| flash&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Internet Explorer 11.0.9600.x&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Linux (Debian Wheezy)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.115&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! OSX 10.9&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 7.0 (9537.71)&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 phone (CyanogenMod, no flash)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 tablet (GalaxyTab2, flash app 11.1.115.36)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 19.0.1340.x&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
! iPhone 4S (6.1.3)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! iPad 4 (7.0.6)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;small&amp;gt;* For HLS/RTMP, html5 in the table means HLS has been used, flash means player fell back and used RTMP.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sub Tasks ==&lt;br /&gt;
&lt;br /&gt;
In initial stage FlowPlayer HTML5 (or any other) will handle all existing HTML5 Video extensions as per core_media_player_html5video class, plus m3u8 (HLS). It will also be possible optionally to make flash files handled by HTML5 Video player as well (possibility of using existing flash FlowPlayer for flv files will remain).&lt;br /&gt;
&lt;br /&gt;
== Mock-Ups/Prototypes ==&lt;br /&gt;
&lt;br /&gt;
See [[#Sample_Pages|Sample pages]] section.&lt;br /&gt;
&lt;br /&gt;
== Workaround ==&lt;br /&gt;
&lt;br /&gt;
As intermediate solution, if you require player consistency throughout all browsers and platforms, you may consider using JW Player filter: https://github.com/lucisgit/moodle-filter_jwplayer Notice, that JW Player is not free for commercial use.&lt;br /&gt;
&lt;br /&gt;
== Related Tracker Issues ==&lt;br /&gt;
* MDL-38158&lt;br /&gt;
&lt;br /&gt;
== Useful links ==&lt;br /&gt;
* http://praegnanz.de/html5video/&lt;br /&gt;
* http://html5video.org/wiki/HTML5_Video_Player_Comparison&lt;br /&gt;
* http://www.streamingmedia.com/Articles/Editorial/Featured-Articles/Choosing-a-Video-Player-Features-and-Specs-for-the-Top-Five-94188.aspx&lt;br /&gt;
&lt;br /&gt;
[[Category:Project]]&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=47488</id>
		<title>HTML5 player</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=47488"/>
		<updated>2015-03-10T11:28:05Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}&lt;br /&gt;
{{Infobox Project&lt;br /&gt;
|name = HTML5 Player with flash fallback&lt;br /&gt;
|state = In Development&lt;br /&gt;
|tracker = https://tracker.moodle.org/browse/MDL-38158&lt;br /&gt;
|discussion = https://moodle.org/mod/forum/discuss.php?d=222753#p1110024&lt;br /&gt;
|assignee = [https://tracker.moodle.org/secure/ViewProfile.jspa?name=kabalin Ruslan Kabalin]&lt;br /&gt;
}}&lt;br /&gt;
{{Moodle 2.x}}&lt;br /&gt;
&lt;br /&gt;
== Project goals ==&lt;br /&gt;
&lt;br /&gt;
The purpose of this document is to choose HTML5 player with flash fallback for integration in Moodle and plan its implementation.&lt;br /&gt;
&lt;br /&gt;
The aim of this change is to reach a consistent look of the player among different platforms and browsers, as well as making sure that player starts using flash if html5 is not supported by browser for the given format. Another aim is to improve accessibility and usability, enhance customisation.&lt;br /&gt;
&lt;br /&gt;
== Considerations ==&lt;br /&gt;
&lt;br /&gt;
* Usability of the player - is it easy to use it and intuitively understand how to use controls?&lt;br /&gt;
* Accessibility of the player - possibility of keyboard navigation, subtitles, support?&lt;br /&gt;
* Appearance of the player - can its interface be modified, themes support, RTL?&lt;br /&gt;
* Consistency among browsers - does player look the same?&lt;br /&gt;
* Audio support - can player handle HTML5 &amp;lt;audio&amp;gt; tag?&lt;br /&gt;
* Mobile platforms support - does player also work on iOS and Android?&lt;br /&gt;
* Streaming media support (including adaptive-bitrate delivery) - can player handle RTMP, Apple HLS, Adobe HDS, Microsoft HSS?&lt;br /&gt;
* Plugins support - can we use or develop community plugins easily?&lt;br /&gt;
* Embedding support - so users could post media content outside Moodle, if permitted.&lt;br /&gt;
* Maintainability of the links between the player and Moodle - how much work will we need to do every time we upgrade?&lt;br /&gt;
&lt;br /&gt;
== Candidates ==&lt;br /&gt;
&lt;br /&gt;
* [http://flowplayer.org/ Flowplayer HTML5]&lt;br /&gt;
* [http://www.videojs.com/ Video.JS]&lt;br /&gt;
* [http://www.projekktor.com/ Projekktor]&lt;br /&gt;
* [http://mediaelementjs.com/ MediaElement.js]&lt;br /&gt;
* ?Are there other alternatives?&lt;br /&gt;
&lt;br /&gt;
== Comparison Matrix ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! [[#Flowplayer_HTML5|Flowplayer HTML5]]&lt;br /&gt;
! [[#Video.JS|Video.JS]]&lt;br /&gt;
! [[#Projekktor|Projekktor]]&lt;br /&gt;
! [[#MediaElement.js|MediaElement.js]]&lt;br /&gt;
! No Player&lt;br /&gt;
|-&lt;br /&gt;
! Accessible Player:&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Keyboard control&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes (configurable)&lt;br /&gt;
| Yes&lt;br /&gt;
| unknown&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Subtitles support&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via plugin)&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (see http://caniuse.com/webvtt)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Touch interface&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Appearance:&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Skins&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* CSS customisation&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| unknown&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTL support&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| No&lt;br /&gt;
| Unknown (CSS, so I guess so...)&lt;br /&gt;
| Unknown&lt;br /&gt;
|-&lt;br /&gt;
! Mobile platforms:&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* iOS&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Android&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Streaming protocols:&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTMP&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via playlist)&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Adaptive HTTP&lt;br /&gt;
| HLS&lt;br /&gt;
| HLS (via plugin)&lt;br /&gt;
| HLS (via playlist)&lt;br /&gt;
| HLS&lt;br /&gt;
| Only in Chrome so far (Media Source Extension)&lt;br /&gt;
|-&lt;br /&gt;
! Audio player&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Embedding support&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (configurable)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via addThis plugin)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via plugin)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | No&lt;br /&gt;
|-&lt;br /&gt;
! License&lt;br /&gt;
| GPL v3 (with additional terms)&lt;br /&gt;
| Apache 2&lt;br /&gt;
| GPL v3&lt;br /&gt;
| no extra code needed&lt;br /&gt;
| MIT&lt;br /&gt;
|-&lt;br /&gt;
! JS library&lt;br /&gt;
| jQuery&lt;br /&gt;
| -&lt;br /&gt;
| jQuery&lt;br /&gt;
| jQuery&lt;br /&gt;
| none required&lt;br /&gt;
|-&lt;br /&gt;
! Plugins infrastructure&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
! Flash fallback player&lt;br /&gt;
| Flowplayer Flash&lt;br /&gt;
| video-js flash&lt;br /&gt;
| StobeMediaPlayback (but can be jarisplayer or some other).&lt;br /&gt;
| Flash and Silverlight (for .wmv support) fallback, used to provide the HTML5 video/audio elements.&lt;br /&gt;
| The Video tag can contain fallback content (e.g. Flash object) for browsers that don&#039;t support it at all (http://camendesign.com/code/video_for_everybody), but not based on codec support.&lt;br /&gt;
|-&lt;br /&gt;
! API&lt;br /&gt;
| Yes (plus window.flowplayer object)&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Flowplayer HTML5 ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* Good looking player, resembles existing flash flowplayer in Moodle (with &amp;quot;functional&amp;quot; skin)&lt;br /&gt;
* Extensive customisation (via CSS3 skins and configuration object)&lt;br /&gt;
* Streaming support (RTMP, HLS)&lt;br /&gt;
* Good accessibility features&lt;br /&gt;
* Configurable embedding functionality&lt;br /&gt;
* Existing flash flowplayer can be configured for fallback (the appearance of player will not be affected).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Require jQuery for functioning&lt;br /&gt;
* Flowplayer logo remains on screen&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using wrapper around &amp;lt;video&amp;gt;.&lt;br /&gt;
* width and height attributes in video tag are ignored, player size is configured via wrapper size only.&lt;br /&gt;
* RTMP server connection is configured via data-rtmp attribute in wrapper or player init config parameter, actual path the file specified in src attribute of source item.&lt;br /&gt;
* &amp;lt;source type=&amp;quot;video/flash&amp;quot;... dummy MIME type to force using plash player for whatever content.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Plugins infrastructure&lt;br /&gt;
* No audio support&lt;br /&gt;
&lt;br /&gt;
=== Video.JS ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Extensive API.&lt;br /&gt;
* No extra JS library needed.&lt;br /&gt;
* Many plugins.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Poor documentation&lt;br /&gt;
* RTMP requires non-standard MIME.&lt;br /&gt;
* Android and iOS override Video.JS with own player, when not overridden, content is not playing.&lt;br /&gt;
* No RTL.&lt;br /&gt;
* HLS support via plugin (many files to include, external contributor see https://github.com/videojs/videojs-contrib-hls).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* RTMP server connection and path specified as single URI in src attribute of source item, &#039;&amp;amp;&#039; character is used as server connection and path divider.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Embedded HLS support.&lt;br /&gt;
&lt;br /&gt;
=== Projekktor ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Well documented API.&lt;br /&gt;
* Media RSS support.&lt;br /&gt;
* Possibility to choose flash player for fallback (included by default are StrobeMediaPlayback and Jarisplayer, both Open Source).&lt;br /&gt;
* Platform preference order selection (e.g. browser, ios, android, flash, native).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Uses flash where it is not supposed to (e.g. mp4 in Chrome).&lt;br /&gt;
* Issues on ios and android (suggests to download file when play button is pressed).&lt;br /&gt;
* RTMP only work if defined via playlist rather than in &amp;lt;source&amp;gt; tags.&lt;br /&gt;
* Subtitles plugin is not free.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* Make sure &amp;lt;video&amp;gt; tag has class attribute with &#039;projekktor&#039; value (even if you initialise it by ID of the element), player will not work properly otherwise.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== MediaElement.js ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* Flash fall-forward - uses Flash/Silverlight to provide the HTML5 MediaElement API.&lt;br /&gt;
* Consistent HTML/CSS Player&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* ...&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* ...&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* ...&lt;br /&gt;
&lt;br /&gt;
=== HTML5 browser native ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* Simple&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* IE8 has no support&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes&#039;&#039;&#039;&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Cross-browser support ==&lt;br /&gt;
&lt;br /&gt;
=== Method ===&lt;br /&gt;
Compatibility checks were done manually by accessing the sample page using different browsers and platforms. Sample page contained the list of identical player instances, initialised for each &amp;lt;video&amp;gt; definition with a &amp;lt;source&amp;gt; of particular format: mp4, webm, ogg, flv. Streaming support was checked by setting up a &amp;lt;video&amp;gt; container with two sources of the same video, one was HLS (Apple HTTP Live Streaming) stream for browsers and platforms that support html5 video streaming, another one was RTMP which is played using flash engine and supposed to be used in case if HLS is not supported.&lt;br /&gt;
&lt;br /&gt;
=== Sample Pages ===&lt;br /&gt;
&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=flowplayer Flowplayer HTML5] version 5.4.6.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=videojs Video.JS] version 4.4.1.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=projekktor Projekktor] version 1.3.09.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=mediaelementjs MediaElement.js] version 2.6.14&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=native Native browser support].&lt;br /&gt;
&lt;br /&gt;
=== Source ===&lt;br /&gt;
&lt;br /&gt;
Source of testing page is hosted on [https://github.com/kabalin/test-html5-players/blob/master/players.php github]. The actual source of the html page can be viewed in browser.&lt;br /&gt;
&lt;br /&gt;
=== Discussion ===&lt;br /&gt;
&lt;br /&gt;
The players comparison that has been carried out demonstrated that &amp;quot;least hassle&amp;quot; player is Flowplayer. Despite some drawbacks listed in [[#Flowplayer_HTML5|corresponding section above]], it is clearly a winner as it works as expected and according to documentation for all browsers and platforms I had chance to test it. This is the only player that supports RTL layout, display platform incompatibility message prior to attempt to play, and was simple to configure (no undocumented tricks that I had to figure out to make it work). Both VideoJS and Projekktor do now perform properly in all cases. Among those two, I personally prefer Projekktor more for its extensive API, plugins infrastructure and configuration flexibility. However problems on mobile platforms and flash fallback inconsistency make them unreliable at this stage.&lt;br /&gt;
&lt;br /&gt;
=== Compatibility results ===&lt;br /&gt;
&lt;br /&gt;
The table was populated using Flowplayer as others do not perform good enough with some formats and platforms, e.g. VideoJS allow mobile platform player to override itself, Projekktor does not always use HTML5 where browser clearly can handle it (supported in native mode and Flowplayer).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Browser&lt;br /&gt;
! mp4&lt;br /&gt;
! webm&lt;br /&gt;
! ogg&lt;br /&gt;
! flv&lt;br /&gt;
! RTMP/HLS*&lt;br /&gt;
|-&lt;br /&gt;
! Windows 7&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Firefox 27.0.1&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 12.16&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 5.1.7&lt;br /&gt;
| flash&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Internet Explorer 11.0.9600.x&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Linux (Debian Wheezy)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.115&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! OSX 10.9&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 7.0 (9537.71)&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 phone (CyanogenMod, no flash)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 tablet (GalaxyTab2, flash app 11.1.115.36)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 19.0.1340.x&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
! iPhone 4S (6.1.3)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! iPad 4 (7.0.6)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;small&amp;gt;* For HLS/RTMP, html5 in the table means HLS has been used, flash means player fell back and used RTMP.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sub Tasks ==&lt;br /&gt;
&lt;br /&gt;
In initial stage FlowPlayer HTML5 (or any other) will handle all existing HTML5 Video extensions as per core_media_player_html5video class, plus m3u8 (HLS). It will also be possible optionally to make flash files handled by HTML5 Video player as well (possibility of using existing flash FlowPlayer for flv files will remain).&lt;br /&gt;
&lt;br /&gt;
== Mock-Ups/Prototypes ==&lt;br /&gt;
&lt;br /&gt;
See [[#Sample_Pages|Sample pages]] section.&lt;br /&gt;
&lt;br /&gt;
== Workaround ==&lt;br /&gt;
&lt;br /&gt;
As intermediate solution, if you require player consistency throughout all browsers and platforms, you may consider using JW Player filter: https://github.com/lucisgit/moodle-filter_jwplayer Notice, that JW Player is not free for commercial use.&lt;br /&gt;
&lt;br /&gt;
== Related Tracker Issues ==&lt;br /&gt;
* MDL-38158&lt;br /&gt;
&lt;br /&gt;
== Useful links ==&lt;br /&gt;
* http://praegnanz.de/html5video/&lt;br /&gt;
* http://html5video.org/wiki/HTML5_Video_Player_Comparison&lt;br /&gt;
* http://www.streamingmedia.com/Articles/Editorial/Featured-Articles/Choosing-a-Video-Player-Features-and-Specs-for-the-Top-Five-94188.aspx&lt;br /&gt;
&lt;br /&gt;
[[Category:Project]]&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=47487</id>
		<title>HTML5 player</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=47487"/>
		<updated>2015-03-10T11:26:50Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: /* Sample Pages */ Add mediaelementjs sample page.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}&lt;br /&gt;
{{Infobox Project&lt;br /&gt;
|name = HTML5 Player with flash fallback&lt;br /&gt;
|state = In Development&lt;br /&gt;
|tracker = https://tracker.moodle.org/browse/MDL-38158&lt;br /&gt;
|discussion = https://moodle.org/mod/forum/discuss.php?d=222753#p1110024&lt;br /&gt;
|assignee = [https://tracker.moodle.org/secure/ViewProfile.jspa?name=kabalin Ruslan Kabalin]&lt;br /&gt;
}}&lt;br /&gt;
{{Moodle 2.x}}&lt;br /&gt;
&lt;br /&gt;
== Project goals ==&lt;br /&gt;
&lt;br /&gt;
The purpose of this document is to choose HTML5 player with flash fallback for integration in Moodle and plan its implementation.&lt;br /&gt;
&lt;br /&gt;
The aim of this change is to reach a consistent look of the player among different platforms and browsers, as well as making sure that player starts using flash if html5 is not supported by browser for the given format. Another aim is to improve accessibility and usability, enhance customisation.&lt;br /&gt;
&lt;br /&gt;
== Considerations ==&lt;br /&gt;
&lt;br /&gt;
* Usability of the player - is it easy to use it and intuitively understand how to use controls?&lt;br /&gt;
* Accessibility of the player - possibility of keyboard navigation, subtitles, support?&lt;br /&gt;
* Appearance of the player - can its interface be modified, themes support, RTL?&lt;br /&gt;
* Consistency among browsers - does player look the same?&lt;br /&gt;
* Audio support - can player handle HTML5 &amp;lt;audio&amp;gt; tag?&lt;br /&gt;
* Mobile platforms support - does player also work on iOS and Android?&lt;br /&gt;
* Streaming media support (including adaptive-bitrate delivery) - can player handle RTMP, Apple HLS, Adobe HDS, Microsoft HSS?&lt;br /&gt;
* Plugins support - can we use or develop community plugins easily?&lt;br /&gt;
* Embedding support - so users could post media content outside Moodle, if permitted.&lt;br /&gt;
* Maintainability of the links between the player and Moodle - how much work will we need to do every time we upgrade?&lt;br /&gt;
&lt;br /&gt;
== Candidates ==&lt;br /&gt;
&lt;br /&gt;
* [http://flowplayer.org/ Flowplayer HTML5]&lt;br /&gt;
* [http://www.videojs.com/ Video.JS]&lt;br /&gt;
* [http://www.projekktor.com/ Projekktor]&lt;br /&gt;
* [http://mediaelementjs.com/ MediaElement.js]&lt;br /&gt;
* ?Are there other alternatives?&lt;br /&gt;
&lt;br /&gt;
== Comparison Matrix ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! [[#Flowplayer_HTML5|Flowplayer HTML5]]&lt;br /&gt;
! [[#Video.JS|Video.JS]]&lt;br /&gt;
! [[#Projekktor|Projekktor]]&lt;br /&gt;
! [[#MediaElement.js|MediaElement.js]]&lt;br /&gt;
! No Player&lt;br /&gt;
|-&lt;br /&gt;
! Accessible Player:&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Keyboard control&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes (configurable)&lt;br /&gt;
| Yes&lt;br /&gt;
| unknown&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Subtitles support&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via plugin)&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (see http://caniuse.com/webvtt)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Touch interface&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Appearance:&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Skins&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* CSS customisation&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| unknown&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTL support&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| No&lt;br /&gt;
| Unknown (CSS, so I guess so...)&lt;br /&gt;
| Unknown&lt;br /&gt;
|-&lt;br /&gt;
! Mobile platforms:&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* iOS&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Android&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Streaming protocols:&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTMP&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via playlist)&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Adaptive HTTP&lt;br /&gt;
| HLS&lt;br /&gt;
| HLS (via plugin)&lt;br /&gt;
| HLS (via playlist)&lt;br /&gt;
| HLS&lt;br /&gt;
| Only in Chrome so far (Media Source Extension)&lt;br /&gt;
|-&lt;br /&gt;
! Audio player&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Embedding support&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (configurable)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via addThis plugin)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via plugin)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | No&lt;br /&gt;
|-&lt;br /&gt;
! License&lt;br /&gt;
| GPL v3 (with additional terms)&lt;br /&gt;
| Apache 2&lt;br /&gt;
| GPL v3&lt;br /&gt;
| no extra code needed&lt;br /&gt;
| MIT&lt;br /&gt;
|-&lt;br /&gt;
! JS library&lt;br /&gt;
| jQuery&lt;br /&gt;
| -&lt;br /&gt;
| jQuery&lt;br /&gt;
| jQuery&lt;br /&gt;
| none required&lt;br /&gt;
|-&lt;br /&gt;
! Plugins infrastructure&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
! Flash fallback player&lt;br /&gt;
| Flowplayer Flash&lt;br /&gt;
| video-js flash&lt;br /&gt;
| StobeMediaPlayback (but can be jarisplayer or some other).&lt;br /&gt;
| Flash and Silverlight (for .wmv support) fallback, used to provide the HTML5 video/audio elements.&lt;br /&gt;
| The Video tag can contain fallback content (e.g. Flash object) for browsers that don&#039;t support it at all (http://camendesign.com/code/video_for_everybody), but not based on codec support.&lt;br /&gt;
|-&lt;br /&gt;
! API&lt;br /&gt;
| Yes (plus window.flowplayer object)&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Flowplayer HTML5 ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* Good looking player, resembles existing flash flowplayer in Moodle (with &amp;quot;functional&amp;quot; skin)&lt;br /&gt;
* Extensive customisation (via CSS3 skins and configuration object)&lt;br /&gt;
* Streaming support (RTMP, HLS)&lt;br /&gt;
* Good accessibility features&lt;br /&gt;
* Configurable embedding functionality&lt;br /&gt;
* Existing flash flowplayer can be configured for fallback (the appearance of player will not be affected).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Require jQuery for functioning&lt;br /&gt;
* Flowplayer logo remains on screen&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using wrapper around &amp;lt;video&amp;gt;.&lt;br /&gt;
* width and height attributes in video tag are ignored, player size is configured via wrapper size only.&lt;br /&gt;
* RTMP server connection is configured via data-rtmp attribute in wrapper or player init config parameter, actual path the file specified in src attribute of source item.&lt;br /&gt;
* &amp;lt;source type=&amp;quot;video/flash&amp;quot;... dummy MIME type to force using plash player for whatever content.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Plugins infrastructure&lt;br /&gt;
* No audio support&lt;br /&gt;
&lt;br /&gt;
=== Video.JS ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Extensive API.&lt;br /&gt;
* No extra JS library needed.&lt;br /&gt;
* Many plugins.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Poor documentation&lt;br /&gt;
* RTMP requires non-standard MIME.&lt;br /&gt;
* Android and iOS override Video.JS with own player, when not overridden, content is not playing.&lt;br /&gt;
* No RTL.&lt;br /&gt;
* HLS support via plugin (many files to include, external contributor see https://github.com/videojs/videojs-contrib-hls).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* RTMP server connection and path specified as single URI in src attribute of source item, &#039;&amp;amp;&#039; character is used as server connection and path divider.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Embedded HLS support.&lt;br /&gt;
&lt;br /&gt;
=== MediaElement.js ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* Flash fall-forward - uses Flash/Silverlight to provide the HTML5 MediaElement API.&lt;br /&gt;
* Consistent HTML/CSS Player&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* ...&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* ...&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* ...&lt;br /&gt;
&lt;br /&gt;
=== Projekktor ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Well documented API.&lt;br /&gt;
* Media RSS support.&lt;br /&gt;
* Possibility to choose flash player for fallback (included by default are StrobeMediaPlayback and Jarisplayer, both Open Source).&lt;br /&gt;
* Platform preference order selection (e.g. browser, ios, android, flash, native).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Uses flash where it is not supposed to (e.g. mp4 in Chrome).&lt;br /&gt;
* Issues on ios and android (suggests to download file when play button is pressed).&lt;br /&gt;
* RTMP only work if defined via playlist rather than in &amp;lt;source&amp;gt; tags.&lt;br /&gt;
* Subtitles plugin is not free.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* Make sure &amp;lt;video&amp;gt; tag has class attribute with &#039;projekktor&#039; value (even if you initialise it by ID of the element), player will not work properly otherwise.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== HTML5 browser native ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* Simple&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* IE8 has no support&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes&#039;&#039;&#039;&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Cross-browser support ==&lt;br /&gt;
&lt;br /&gt;
=== Method ===&lt;br /&gt;
Compatibility checks were done manually by accessing the sample page using different browsers and platforms. Sample page contained the list of identical player instances, initialised for each &amp;lt;video&amp;gt; definition with a &amp;lt;source&amp;gt; of particular format: mp4, webm, ogg, flv. Streaming support was checked by setting up a &amp;lt;video&amp;gt; container with two sources of the same video, one was HLS (Apple HTTP Live Streaming) stream for browsers and platforms that support html5 video streaming, another one was RTMP which is played using flash engine and supposed to be used in case if HLS is not supported.&lt;br /&gt;
&lt;br /&gt;
=== Sample Pages ===&lt;br /&gt;
&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=flowplayer Flowplayer HTML5] version 5.4.6.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=videojs Video.JS] version 4.4.1.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=projekktor Projekktor] version 1.3.09.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=mediaelementjs MediaElement.js] version 2.6.14&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=native Native browser support].&lt;br /&gt;
&lt;br /&gt;
=== Source ===&lt;br /&gt;
&lt;br /&gt;
Source of testing page is hosted on [https://github.com/kabalin/test-html5-players/blob/master/players.php github]. The actual source of the html page can be viewed in browser.&lt;br /&gt;
&lt;br /&gt;
=== Discussion ===&lt;br /&gt;
&lt;br /&gt;
The players comparison that has been carried out demonstrated that &amp;quot;least hassle&amp;quot; player is Flowplayer. Despite some drawbacks listed in [[#Flowplayer_HTML5|corresponding section above]], it is clearly a winner as it works as expected and according to documentation for all browsers and platforms I had chance to test it. This is the only player that supports RTL layout, display platform incompatibility message prior to attempt to play, and was simple to configure (no undocumented tricks that I had to figure out to make it work). Both VideoJS and Projekktor do now perform properly in all cases. Among those two, I personally prefer Projekktor more for its extensive API, plugins infrastructure and configuration flexibility. However problems on mobile platforms and flash fallback inconsistency make them unreliable at this stage.&lt;br /&gt;
&lt;br /&gt;
=== Compatibility results ===&lt;br /&gt;
&lt;br /&gt;
The table was populated using Flowplayer as others do not perform good enough with some formats and platforms, e.g. VideoJS allow mobile platform player to override itself, Projekktor does not always use HTML5 where browser clearly can handle it (supported in native mode and Flowplayer).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Browser&lt;br /&gt;
! mp4&lt;br /&gt;
! webm&lt;br /&gt;
! ogg&lt;br /&gt;
! flv&lt;br /&gt;
! RTMP/HLS*&lt;br /&gt;
|-&lt;br /&gt;
! Windows 7&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Firefox 27.0.1&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 12.16&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 5.1.7&lt;br /&gt;
| flash&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Internet Explorer 11.0.9600.x&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Linux (Debian Wheezy)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.115&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! OSX 10.9&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 7.0 (9537.71)&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 phone (CyanogenMod, no flash)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 tablet (GalaxyTab2, flash app 11.1.115.36)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 19.0.1340.x&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
! iPhone 4S (6.1.3)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! iPad 4 (7.0.6)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;small&amp;gt;* For HLS/RTMP, html5 in the table means HLS has been used, flash means player fell back and used RTMP.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sub Tasks ==&lt;br /&gt;
&lt;br /&gt;
In initial stage FlowPlayer HTML5 (or any other) will handle all existing HTML5 Video extensions as per core_media_player_html5video class, plus m3u8 (HLS). It will also be possible optionally to make flash files handled by HTML5 Video player as well (possibility of using existing flash FlowPlayer for flv files will remain).&lt;br /&gt;
&lt;br /&gt;
== Mock-Ups/Prototypes ==&lt;br /&gt;
&lt;br /&gt;
See [[#Sample_Pages|Sample pages]] section.&lt;br /&gt;
&lt;br /&gt;
== Workaround ==&lt;br /&gt;
&lt;br /&gt;
As intermediate solution, if you require player consistency throughout all browsers and platforms, you may consider using JW Player filter: https://github.com/lucisgit/moodle-filter_jwplayer Notice, that JW Player is not free for commercial use.&lt;br /&gt;
&lt;br /&gt;
== Related Tracker Issues ==&lt;br /&gt;
* MDL-38158&lt;br /&gt;
&lt;br /&gt;
== Useful links ==&lt;br /&gt;
* http://praegnanz.de/html5video/&lt;br /&gt;
* http://html5video.org/wiki/HTML5_Video_Player_Comparison&lt;br /&gt;
* http://www.streamingmedia.com/Articles/Editorial/Featured-Articles/Choosing-a-Video-Player-Features-and-Specs-for-the-Top-Five-94188.aspx&lt;br /&gt;
&lt;br /&gt;
[[Category:Project]]&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Acceptance_testing&amp;diff=47320</id>
		<title>Acceptance testing</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Acceptance_testing&amp;diff=47320"/>
		<updated>2015-02-03T11:34:59Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: /* Output formats */ Added a note about &amp;quot;-f pretty&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
This page describes how we describe Moodle&#039;s functionalities and automatically test them.&lt;br /&gt;
&lt;br /&gt;
Behat is a behavioural driven development (BDD) tool written in PHP, it can parse a human-readable list of sentences (called steps) and execute actions in a browser using Selenium or other tools to simulate user interactions.&lt;br /&gt;
&lt;br /&gt;
For technical info: [[Behat integration]]&lt;br /&gt;
&lt;br /&gt;
=== How it works ===&lt;br /&gt;
Behat parses and executes features files which describe Moodle&#039;s features (for example &#039;&#039;Post in a forum&#039;&#039;). Each feature file is composed of many scenarios (for example &#039;&#039;Add a post to a discussion&#039;&#039; or &#039;&#039;Create a new discussion&#039;&#039;), and finally each scenario is composed of steps (for example  &#039;&#039;I press &amp;quot;Post to forum&amp;quot;&#039;&#039; or &#039;&#039;I should see &amp;quot;My post title&amp;quot;&#039;&#039;). When the feature file is executed, every step internally is translated into a PHP method and is executed.&lt;br /&gt;
&lt;br /&gt;
These features are executed nightly on the HQ servers using all the supported databases (MySQL, PostgreSQL, MSSQL and Oracle) and with different browsers (Firefox, Internet Explorer, Safari and Chrome) to avoid regressions and to test new functionalities.&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
&lt;br /&gt;
Note that these snippets are only examples and may not work.&lt;br /&gt;
&lt;br /&gt;
* There is a closed list of steps to use in the features, a feature written with the basic (or low-level) steps looks like this:&lt;br /&gt;
  @auth&lt;br /&gt;
  &#039;&#039;&#039;Feature&#039;&#039;&#039;: Login&lt;br /&gt;
    In order to login&lt;br /&gt;
    As a moodle user&lt;br /&gt;
    I need to be able to validate the username and password against moodle&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;Scenario&#039;&#039;&#039;: Login as an existing user&lt;br /&gt;
      Given I am on &amp;quot;login/index.php&amp;quot;&lt;br /&gt;
      When I fill in &amp;quot;username&amp;quot; with &amp;quot;admin&amp;quot;&lt;br /&gt;
      And I fill in &amp;quot;password&amp;quot; with &amp;quot;moodle&amp;quot;&lt;br /&gt;
      And I press &amp;quot;loginbtn&amp;quot;&lt;br /&gt;
      Then I should see &amp;quot;Moodle 101: Course Name&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;Scenario&#039;&#039;&#039;: Login as an unexisting user&lt;br /&gt;
      Given I am on &amp;quot;login/index.php&amp;quot;&lt;br /&gt;
      When I fill in &amp;quot;username&amp;quot; with &amp;quot;admin&amp;quot;&lt;br /&gt;
      And I fill in &amp;quot;password&amp;quot; with &amp;quot;moodle&amp;quot;&lt;br /&gt;
      And I press &amp;quot;loginbtn&amp;quot;&lt;br /&gt;
      Then I should see &amp;quot;Moodle 101: Course Name&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Note that The 3 sentences below &#039;&#039;Feature: Login&#039;&#039; are only information about what we want to test.&lt;br /&gt;
&lt;br /&gt;
These are simple scenarios, but most of Moodle&#039;s functionalities would require a huge list of this steps to test a scenario, imagine a &#039;&#039;Add a post to a discussion&#039;&#039; scenario; you need to login, create a course, create a user and enrol it in the course... Most of this steps is not what we intend to test in a &#039;&#039;Post in a forum&#039;&#039; feature, Moodle provides extra steps to quickly set up the context required to test a Moodle feature, for example:&lt;br /&gt;
&lt;br /&gt;
  @mod @mod_forum&lt;br /&gt;
  &#039;&#039;&#039;Feature&#039;&#039;&#039;: Add forum activities and discussions&lt;br /&gt;
    In order to discuss topics with other users&lt;br /&gt;
    As a moodle teacher&lt;br /&gt;
    I need to add forum activities to moodle courses&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;Scenario&#039;&#039;&#039;: Add a forum and a discussion&lt;br /&gt;
      &#039;&#039;&#039;Given&#039;&#039;&#039; the following &amp;quot;users&amp;quot; exists:&lt;br /&gt;
        | username | firstname | lastname | email |&lt;br /&gt;
        | teacher1 | Teacher | 1 | teacher1@asd.com |&lt;br /&gt;
      &#039;&#039;&#039;And&#039;&#039;&#039; the following &amp;quot;courses&amp;quot; exists:&lt;br /&gt;
        | fullname | shortname | category |&lt;br /&gt;
        | Course 1 | C1 | 0 |&lt;br /&gt;
      &#039;&#039;&#039;And&#039;&#039;&#039; the following &amp;quot;course enrolments&amp;quot; exists:&lt;br /&gt;
        | user | course | role |&lt;br /&gt;
        | teacher1 | C1 | editingteacher |&lt;br /&gt;
      &#039;&#039;&#039;And&#039;&#039;&#039; I log in as &amp;quot;teacher1&amp;quot;&lt;br /&gt;
      &#039;&#039;&#039;And&#039;&#039;&#039; I follow &amp;quot;Course 1&amp;quot;&lt;br /&gt;
      &#039;&#039;&#039;And&#039;&#039;&#039; I turn editing mode on&lt;br /&gt;
      &#039;&#039;&#039;And&#039;&#039;&#039; I add a &amp;quot;Forum&amp;quot; to section &amp;quot;1&amp;quot; and I fill the form with:&lt;br /&gt;
        | Forum name | Test forum name |&lt;br /&gt;
        | Forum type | Standard forum for general use |&lt;br /&gt;
        | Description | Test forum description |&lt;br /&gt;
      &#039;&#039;&#039;When&#039;&#039;&#039; I add a new discussion to &amp;quot;Test forum name&amp;quot; forum with:&lt;br /&gt;
        | Subject | Forum post subject |&lt;br /&gt;
        | Message | This is the body |&lt;br /&gt;
      &#039;&#039;&#039;Then&#039;&#039;&#039; I should see &amp;quot;Test forum name&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Note that:&lt;br /&gt;
&lt;br /&gt;
* Each scenario is executed in an isolated testing environment, so the first step begins with an empty moodle site and what you set up in an scenario (like the &#039;&#039;Test forum name&#039;&#039; forum in the example above) is cleaned up after the scenario execution&lt;br /&gt;
* The prefixes &amp;quot;Given&amp;quot;, &amp;quot;When&amp;quot; and &amp;quot;Then&amp;quot; are only informative and they are used to define the context (Given), specify the action (When) and check the results (Then), using them properly helps to understand what the scenario is testing.&lt;br /&gt;
&lt;br /&gt;
== Quick start ==&lt;br /&gt;
&lt;br /&gt;
This is a quick introduction to write a functional test (acceptance tests) using steps in a development/testing site, please DON&#039;T USE THIS IN A PRODUCTION SITE.&lt;br /&gt;
&lt;br /&gt;
To let you experience the pleasure of watching a feature file doing &amp;quot;your work&amp;quot; automatically in a real browser, this guide includes 2 optional steps to download Selenium and run it in another CLI.&lt;br /&gt;
&lt;br /&gt;
# Open a command line interface&lt;br /&gt;
# &#039;&#039;&#039;cd /to/your/moodle/dirroot&#039;&#039;&#039;&lt;br /&gt;
# Edit config.php adding the following lines before the lib/setup.php include&lt;br /&gt;
#: &amp;lt;code language=&amp;quot;text&amp;quot;&amp;gt;$CFG-&amp;gt;behat_prefix = &#039;b_&#039;;&lt;br /&gt;
$CFG-&amp;gt;behat_dataroot = &#039;/path/to/your/behat/dataroot/directory&#039;;&lt;br /&gt;
$CFG-&amp;gt;behat_wwwroot = &#039;http://127.0.0.1&#039;; // must be different from wwwroot&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
# &#039;&#039;&#039;curl http://getcomposer.org/installer | php&#039;&#039;&#039; (In case you have problems read https://docs.moodle.org/dev/Acceptance_testing#Installation)&lt;br /&gt;
# &#039;&#039;&#039;php admin/tool/behat/cli/init.php&#039;&#039;&#039;&lt;br /&gt;
# Download selenium-server-standalone-2.NN.N.jar from http://seleniumhq.org/download/, under &amp;quot;Selenium server (formerly the Selenium RC Server)&amp;quot;&lt;br /&gt;
# Open another command line interface and run &#039;&#039;&#039;java -jar /path/to/your/selenium/server/selenium-server-standalone-2.NN.N.jar&#039;&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;vendor/bin/behat --config /path/to/your/behat/dataroot/directory/behat/behat.yml&#039;&#039;&#039;&lt;br /&gt;
# You just ran the current Moodle tests, now let&#039;s add your own test, add a blog entry for example&lt;br /&gt;
# Browse to your $CFG-&amp;gt;behat_wwwroot, this is an empty test site and it is reset before each test (called scenario)&lt;br /&gt;
# From this point follow the steps you would follow to add manually a blog entry (login credentials are admin/admin)&lt;br /&gt;
# When you are done go to &#039;Site administration&#039; -&amp;gt; &#039;Development&#039; -&amp;gt; &#039;Acceptance testing&#039;, you will find the list of &amp;quot;actions&amp;quot; that can be run automatically, you can filter them to find what do you need to do (more steps can be added if you need, more info in https://docs.moodle.org/dev/Acceptance_testing#Adding_steps_definitions)&lt;br /&gt;
# To &#039;add a blog entry&#039; we need to:&lt;br /&gt;
## Log in the system as a valid user&lt;br /&gt;
## Expand &#039;My profile&#039; node of the navigation block&lt;br /&gt;
## Expand the &#039;Blogs&#039; node of the navigation block&lt;br /&gt;
## Follow he &#039;Add a new entry&#039; link&lt;br /&gt;
## Fill the moodle form with values for &#039;Entry title&#039; and &#039;Blog entry body&#039;&lt;br /&gt;
## Press the &#039;Save changes&#039; button&lt;br /&gt;
## Verify you see the values you entered in the form and verify you are not in the form page&lt;br /&gt;
# This translated to steps is:&lt;br /&gt;
#: &amp;lt;code language=&amp;quot;text&amp;quot;&amp;gt;Given I log in as &amp;quot;admin&amp;quot;&lt;br /&gt;
And I expand &amp;quot;My profile&amp;quot; node&lt;br /&gt;
And I expand &amp;quot;Blogs&amp;quot; node&lt;br /&gt;
And I follow &amp;quot;Add a new entry&amp;quot;&lt;br /&gt;
And I set the following fields to these values:&lt;br /&gt;
  | Entry title | I&#039;m the name |&lt;br /&gt;
  | Blog entry body | I&#039;m the description |&lt;br /&gt;
When I press &amp;quot;Save changes&amp;quot;&lt;br /&gt;
Then I should see &amp;quot;User Blog&amp;quot;&lt;br /&gt;
And I should see &amp;quot;I&#039;m the description&amp;quot;&lt;br /&gt;
And I should not see &amp;quot;Required&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
# We need to wrap this steps following the behavior driven development guidelines (more info in https://docs.moodle.org/dev/Acceptance_testing#Writing_features)&lt;br /&gt;
#: &amp;lt;code language=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
@core @core_blog&lt;br /&gt;
Feature: Add a blog entry&lt;br /&gt;
  In order to let the world know about me&lt;br /&gt;
  As a user&lt;br /&gt;
  I need to write blog entries&lt;br /&gt;
&lt;br /&gt;
  @javascript&lt;br /&gt;
  Scenario: Add a blog entry with valid data&lt;br /&gt;
    Given I log in as &amp;quot;admin&amp;quot;&lt;br /&gt;
    And I expand &amp;quot;My profile&amp;quot; node&lt;br /&gt;
    And I expand &amp;quot;Blogs&amp;quot; node&lt;br /&gt;
    And I follow &amp;quot;Add a new entry&amp;quot;&lt;br /&gt;
    And I fill the moodle form with:&lt;br /&gt;
      | Entry title | I&#039;m the name |&lt;br /&gt;
      | Blog entry body | I&#039;m the description |&lt;br /&gt;
    When I press &amp;quot;Save changes&amp;quot;&lt;br /&gt;
    Then I should see &amp;quot;View all of my entries&amp;quot;&lt;br /&gt;
    And I should see &amp;quot;I&#039;m a description&amp;quot;&lt;br /&gt;
    And I should not see &amp;quot;Required&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
# And save it into a file, in this case &#039;&#039;&#039;blog/tests/behat/add_entry.feature&#039;&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;php admin/tool/behat/cli/util.php --enable&#039;&#039;&#039;  (This will update the available tests and steps definitions)&lt;br /&gt;
# &#039;&#039;&#039;vendor/bin/behat --config /path/to/your/behat/dataroot/directory/behat/behat.yml --tags @core_blog&#039;&#039;&#039;&lt;br /&gt;
# Selenium will open a browser (firefox by default) and you will see how the steps you have been writting are executed&lt;br /&gt;
&lt;br /&gt;
You can also try to expand non existing nodes or change the &#039;Then&#039; assertions to get a beautiful failure.&lt;br /&gt;
&lt;br /&gt;
For detailed steps and/or troubleshooting:&lt;br /&gt;
* https://docs.moodle.org/dev/Acceptance_testing#Running_tests&lt;br /&gt;
* https://docs.moodle.org/dev/Acceptance_testing#Writing_features&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
* PHP 5.4 (see https://docs.moodle.org/dev/Acceptance_testing#Advanced_usage for PHP 5.3, only for non-production sites)&lt;br /&gt;
* Other dependencies are managed by the composer installer&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
* Edit config.php&lt;br /&gt;
** Use $CFG-&amp;gt;behat_dataroot to set the directory where behat test environment dataroot will be stored, something like &#039;&#039;&#039;$CFG-&amp;gt;behat_dataroot = &#039;/your/directory/path&#039;;&#039;&#039;&#039;. Ensure the directory can be created or have write permissions&lt;br /&gt;
** Use $CFG-&amp;gt;behat_prefix to set the database prefix of the behat test environment database tables, something like &#039;&#039;&#039;$CFG-&amp;gt;behat_prefix = &#039;behat_&#039;;&#039;&#039;&#039;&lt;br /&gt;
** Use $CFG-&amp;gt;behat_wwwroot to set address to be used to access behat instance. It has to be different from $CFG-&amp;gt;wwwroot, you can use for example localhost, 127.0.0.1 or any custom local host name specified in you /etc/hosts. If you use the built-in PHP server use &amp;quot;http://localhost:8000&amp;quot; or the value you set when you started it.&lt;br /&gt;
* Download composer&lt;br /&gt;
** &#039;&#039;&#039;cd /your/moodle/dirroot&#039;&#039;&#039;&lt;br /&gt;
** &#039;&#039;&#039;curl http://getcomposer.org/installer | php&#039;&#039;&#039;&lt;br /&gt;
*** If you don&#039;t have curl installed or you have problems running &#039;&#039;&#039;curl http://getcomposer.org/installer | php&#039;&#039;&#039;:&lt;br /&gt;
**** Download &#039;&#039;&#039;http://getcomposer.org/installer&#039;&#039;&#039;&lt;br /&gt;
**** Store it in /your/moodle/dirroot/composerinstaller.php for example&lt;br /&gt;
**** Run it from /your/moodle/dirroot with &#039;&#039;&#039;php composerinstaller.php&#039;&#039;&#039;, you can delete this file after running the next step (&#039;&#039;&#039;php composer.phar update --dev&#039;&#039;&#039;)&lt;br /&gt;
* Install behat dependencies and enable the test environment&lt;br /&gt;
** &#039;&#039;&#039;cd /your/moodle/dirroot&#039;&#039;&#039;&lt;br /&gt;
** &#039;&#039;&#039;php admin/tool/behat/cli/init.php&#039;&#039;&#039;&lt;br /&gt;
* (Optional) If you want to run tests that involves Javascript (most of them) you will also need Selenium&lt;br /&gt;
** Download it from http://seleniumhq.org/download/, named &amp;quot;Selenium server (formerly the Selenium RC Server)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Verify your installation ==&lt;br /&gt;
* Test your installation by browsing your /admin/tool/behat/index.php page.&lt;br /&gt;
If you are using MAMP/WAMP/XAMPP and don&#039;t get the report working... then you need to ensure that your web servers knows where the PHP executable (commad line) is. To do that, edit the &amp;quot;envvars&amp;quot; file (usually under library/bin) and add to $PATH the path to your php executable. Then restart the apache server and try again.&lt;br /&gt;
For example, for MAMP you probably need to add:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
# Adding MAMP binaries communicate where CLI is&lt;br /&gt;
PATH=&amp;quot;/Applications/MAMP/bin/php/php5.x.y/bin:$PATH&amp;quot;; export PATH &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
at the end of MAMP/Library/bin/envvars.&lt;br /&gt;
&lt;br /&gt;
== Running tests ==&lt;br /&gt;
# (Optional) Start the PHP built-in web server if you configured the $CFG-&amp;gt;behat_wwwroot to use it:&lt;br /&gt;
#* Open a command line interface and &#039;&#039;&#039;cd /to/your/moodle/dirroot&#039;&#039;&#039;&lt;br /&gt;
#* &#039;&#039;&#039;php -S localhost:8000&#039;&#039;&#039; (This is the test site URL that moodle uses by default, if you want to use another one you can override it in config.php with $CFG-&amp;gt;behat_wwwroot attribute; more info in https://docs.moodle.org/dev/Acceptance_testing#Advanced_usage or config-dist.php)&lt;br /&gt;
# (Optional) Start the Selenium server (in case you want to run tests that involves Javascript)&lt;br /&gt;
#* (See http://www.installationpage.com/selenium/how-to-run-selenium-headless-firefox-in-ubuntu/ for running &#039;headless&#039; Firefox and xvfm in a server environment)&lt;br /&gt;
#* Open another command line interface and &#039;&#039;&#039;java -jar /path/to/your/selenium/server/selenium-server-standalone-2.NN.N.jar&#039;&#039;&#039;&lt;br /&gt;
# Run Behat&lt;br /&gt;
#* &#039;&#039;&#039;vendor/bin/behat --config /path/to/your/CFG_behat_dataroot/behat/behat.yml&#039;&#039;&#039; (For more options &#039;&#039;&#039;vendor/bin/behat --help&#039;&#039;&#039; or http://docs.behat.org/guides/6.cli.html)&lt;br /&gt;
#* In case you don&#039;t want to run Javascript tests use the Behat tags option to skip them, &#039;&#039;&#039;vendor/bin/behat --tags ~@javascript --config /path/to/your/CFG_behat_dataroot/behat/behat.yml&#039;&#039;&#039;&lt;br /&gt;
#* If you followed all the steps and you receive an unknown weird error probably your system&#039;s Firefox version is not compatible with the Selenium version you are running, try downloading the latest Selenium release from it&#039;s website as explained above&lt;br /&gt;
# (Optional) If you are adding new tests or steps definitions update the tests list:&lt;br /&gt;
#* &#039;&#039;&#039;php admin/tool/behat/cli/util.php --enable&#039;&#039;&#039;&lt;br /&gt;
# (Optional) Disable test environment (if you want to prevent access to test environment)&lt;br /&gt;
#* &#039;&#039;&#039;php admin/tool/behat/cli/util.php --disable&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note that if you have the HTTP_PROXY environment variable set, which you may have had to do to run composer, then you also need to set NO_PROXY=localhost.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Tests filters ===&lt;br /&gt;
With the &#039;&#039;&#039;--tags&#039;&#039;&#039; or the &#039;&#039;&#039;-name&#039;&#039;&#039; Behat options you can filter which tests are going to run or which ones are going to be skipped. There are a few tags that you might be interested in:&lt;br /&gt;
* &#039;&#039;&#039;@javascript&#039;&#039;&#039;: All the tests that runs in a browser using Javascript; they require Selenium to be running, otherwise an exception will be thrown.&lt;br /&gt;
* &#039;&#039;&#039;@_file_upload&#039;&#039;&#039;: All the tests that involves file uploading or any OS feature that is not 100% part of the browser. They should only be executed when Selenium is running in the same machine where the tests are running.&lt;br /&gt;
* &#039;&#039;&#039;@_alert&#039;&#039;&#039;: All the tests that involves Javascript dialogs (alerts, confirms...) are using a feature that is OS-dependant and out of the browser scope, so they should be tag appropriately as not all browsers manage them properly.&lt;br /&gt;
* &#039;&#039;&#039;@_switch_window&#039;&#039;&#039;: All the tests that are using the &#039;&#039;&#039;I switch to &amp;quot;NAME&amp;quot; window&#039;&#039;&#039; step should be tagged as not all browsers manage them properly.&lt;br /&gt;
* &#039;&#039;&#039;@_switch_iframe&#039;&#039;&#039;: All the tests that are using the &#039;&#039;&#039;I switch to &amp;quot;NAME&amp;quot; window&#039;&#039;&#039; steps should be tagged as it is an advanced feature and some browsers may have problems dealing with them&lt;br /&gt;
* &#039;&#039;&#039;@_cross_browser&#039;&#039;&#039;: All the tests that should run against multiple combinations of browsers + OS in a regular basis. The features that are sensitive to different combinations of OS and browsers should be tagges as @_cross_browser.&lt;br /&gt;
* &#039;&#039;&#039;@componentname&#039;&#039;&#039;: Moodle features uses the [https://docs.moodle.org/dev/Frankenstyle Frankenstyle] component name to tag the features according to the Moodle subsystem they belong to.&lt;br /&gt;
&lt;br /&gt;
=== Output formats ===&lt;br /&gt;
&lt;br /&gt;
If you want to see the failures immediately (rather than waiting ~3 hours for all the tests to finish) then either use the -v option to output a bit more information, or change the output format using --format. Format &#039;pretty&#039; (&#039;&#039;&#039;-f pretty&#039;&#039;&#039;) is sufficient for most cases, as it outputs each step outcomes in the command line making easier to see the progress.&lt;br /&gt;
&lt;br /&gt;
== Run behat using different browsers ==&lt;br /&gt;
&lt;br /&gt;
Following these instructions you can run behat in Firefox browser through Selenium, but you can run behat using different browsers through Selenium and even use phantomjs (Webkit). [[Acceptance_testing/Browsers|More info]]&lt;br /&gt;
&lt;br /&gt;
== Advanced usage ==&lt;br /&gt;
There are a few settings for advanced use of Behat and execution in continuous integration systems, by default all this options are disabled, use this settings only if you know what you are doing.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Different test server URL&#039;&#039;&#039;. If for example your are interested in allowing accesses from your local network because your Jenkins server is there you can set $CFG-&amp;gt;behat_wwwroot to &#039;&#039;&#039;http://my.computer.local.ip:8000&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Behat configuration&#039;&#039;&#039;, Moodle writes a behat.yml config file with info about the available tests and steps definitions along with other Behat parameters, you can override the Behat parameters we set and add your new parameters, your parameters will be merged with the Moodle ones giving priority to your values in case of conflict. This is useful for an advanced use of Behat, with multiple profiles, output formats, integration with continuous servers... &lt;br /&gt;
* &#039;&#039;&#039;Save screenshots of failures&#039;&#039;&#039;. You can use $CFG-&amp;gt;behat_faildump_path to specify a directory where behat will generate a screenshot with the browser state each time a scenario fails. This is useful to detect where the problem was and work on a solution.&lt;br /&gt;
* &#039;&#039;&#039;Running with a browser other than Firefox&#039;&#039;&#039;, by adding the following code to your config.php you can change the selected browser that is run when behat is invoked. In this case Chrome is selected, but internet explorer, firefox, iphone, android, chrome, htmlunit should be valid options. You will need to run &#039;&#039;&#039;php admin/tool/behat/cli/init.php&#039;&#039;&#039; for changes to take effect.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code language=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$CFG-&amp;gt;behat_config = array(&lt;br /&gt;
    &#039;default&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;extensions&#039; =&amp;gt; array(&lt;br /&gt;
            &#039;Behat\MinkExtension\Extension&#039; =&amp;gt; array(&lt;br /&gt;
                &#039;selenium2&#039; =&amp;gt; array(&lt;br /&gt;
                    &#039;browser&#039; =&amp;gt; &#039;chrome&#039;&lt;br /&gt;
                )&lt;br /&gt;
            )&lt;br /&gt;
        )&lt;br /&gt;
    )&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:Note that for Chrome, you will need the Selenium Chrome Driver (https://code.google.com/p/selenium/wiki/ChromeDriver), and it will need to be installed in the command search path.&lt;br /&gt;
* &#039;&#039;&#039;Switch completely to test environment&#039;&#039;&#039; option was removed in 2.7, it is recommended to always set $CFG-&amp;gt;behat_wwwroot even in older versions instead.&lt;br /&gt;
* Note that when using cloud-based systems that can make use of non-standard capabilities like Saucelabs, you might want to provide configuration attributes containing the &#039;&#039;&#039;&#039;-&#039;&#039;&#039;&#039; character, which is automatically converted to &#039;&#039;&#039;&#039;_&#039;&#039;&#039;&#039; by the Symfony configuration manager that Behat is making use of (@see Symfony\Component\Config\Definition\Processor::normalizeKeys()) a way to avoid this restriction is to, adding to the vars you set like &#039;&#039;&#039;&#039;max-duration&#039;&#039;&#039;&#039; add the same var replacing dashes for underscores, this way the configuration manager will maintain the attribute containing dashes.&lt;br /&gt;
* &#039;&#039;&#039;Extra allowed settings&#039;&#039;&#039;, moodle allows users to define many settings in config.php (see config-dist.php) when running the behat test site those settings are skipped to avoid interaction with the production environment, in case you are interested in allowing some of those extra settings to run the tests using a configuration similar to the one you are using in your production environment you can whitelist them adding them to $CFG-&amp;gt;behat_extraallowedsettings (see config-dist.php for examples).&lt;br /&gt;
You can find more info and examples of how to use this settings in the config-dist.php file included in the Moodle codebase.&lt;br /&gt;
&lt;br /&gt;
== Contributing ==&lt;br /&gt;
&lt;br /&gt;
You can contribute the effort to automatically test all of Moodle&#039;s functionalities, please follow the [[contributor guide|https://docs.moodle.org/dev/Acceptance_testing/Contributing_automated_tests]]. Here you can find information about [[Acceptance_testing#Writing_features|how to write new features]] and [[Acceptance_testing#Adding_steps_definitions|how to write new step definitions]] if your changes requires a base change in the [https://github.com/moodlehq/moodle-behat-extension Moodle behat extension] you can find here how to do it following the integration workflow: https://docs.moodle.org/dev/Acceptance_testing/Contributing_to_Moodle_behat_extension.&lt;br /&gt;
&lt;br /&gt;
== Writing features ==&lt;br /&gt;
&lt;br /&gt;
All Moodle components and plugins (including 3rd party plugins) can specify their tests in .feature files using all the available steps.&lt;br /&gt;
&lt;br /&gt;
Once you decided which functionality you want to specify as a feature you should:&lt;br /&gt;
# Select the most appropriate Moodle component to include your test and create a COMPONENTNAME/tests/behat/FEATURENAME.feature file&lt;br /&gt;
# Add a tag with the component name in Frankenstyle format (https://docs.moodle.org/dev/Frankenstyle) on the first line along with the plugin type or @core if it&#039;s a core subsystem&lt;br /&gt;
# Begin writing the user story of the feature, including in the &#039;As a ...&#039; statement the main beneficiary of the feature:&lt;br /&gt;
#: &amp;lt;code lang=&amp;quot;yaml&amp;quot;&amp;gt;@plugintype @plugintype_pluginname&lt;br /&gt;
Feature: FEATURENAME&lt;br /&gt;
  In order to ...    // Why this feature is useful&lt;br /&gt;
  As ...    // It can be &#039;an admin&#039;, &#039;a teacher&#039;, &#039;a student&#039;, &#039;a guest&#039;, &#039;a user&#039;, &#039;a tests writer&#039; and &#039;a developer&#039;&lt;br /&gt;
  I need to ...      // The feature we want&amp;lt;/code&amp;gt;&lt;br /&gt;
# From the beneficiary point of view, think of different scenarios to ensure the feature works as expected&lt;br /&gt;
# For each scenario you thought:&lt;br /&gt;
## Think of the initial context you need, for example &#039;&#039;1 course with 2 students on it and an assignment&#039;&#039;, and which steps do you need to follow (interacting with the browser) to verify the scenario works as expected&lt;br /&gt;
## What you are testing requires Javascript? Think only on the feature you are testing (for example if you want to test that you can view your profile you don&#039;t need Javascript to click on a link and assert against plain HTML, but if you want to test something related with the course&#039;s gradebook you might want to test it with Javascript)&lt;br /&gt;
## Check the steps list (more info in https://docs.moodle.org/dev/Acceptance_testing#Available_steps) and set the initial context data (see https://docs.moodle.org/dev/Acceptance_testing#Fixtures for more info) and the steps to follow to verify all works as it should work. &lt;br /&gt;
## The prefixes &#039;&#039;Given&#039;&#039;, &#039;&#039;When&#039;&#039; and &#039;&#039;Then&#039;&#039; separates the scenario in 3 parts, the initial context setup (&#039;&#039;Given&#039;&#039;), the action that provokes a change in the system (&#039;&#039;When&#039;&#039;) and the validation of that change outcomes (&#039;&#039;Then&#039;&#039;) So with a quick view at the scenario you can see what it is testing as the prefixes will be something like Given -&amp;gt; And -&amp;gt; And -&amp;gt; When -&amp;gt; And -&amp;gt; And -&amp;gt; Then -&amp;gt; And -&amp;gt; And -&amp;gt; And. Once we begin with the first &#039;&#039;Then&#039;&#039; we can consider that we are checking the outcomes so all the steps from there should be prefixed with &#039;&#039;Then&#039;&#039;&lt;br /&gt;
## Copy the list of steps to the .feature file with the Scenario header:&lt;br /&gt;
##: &amp;lt;code lang=&amp;quot;yaml&amp;quot;&amp;gt;Scenario: Short description of the scenario&lt;br /&gt;
  Given step 1&lt;br /&gt;
  And step 2&lt;br /&gt;
  And step 3&lt;br /&gt;
  When step 4&lt;br /&gt;
  And step 5&lt;br /&gt;
  Then step 6&amp;lt;/code&amp;gt;&lt;br /&gt;
## If the steps you are using requires Javascript add the @javascript tag above the &amp;quot;Scenario:&amp;quot; headline&lt;br /&gt;
##:    &amp;lt;code lang=&amp;quot;yaml&amp;quot;&amp;gt;@javascript&lt;br /&gt;
Scenario: Short description of the scenario&lt;br /&gt;
  ...&lt;br /&gt;
  ...&amp;lt;/code&amp;gt;&lt;br /&gt;
# Run the tests, when creating your new features/scenarios you can specify a &#039;@wip&#039; (work in progress) tag in both the line above the Scenario description and the tests runner (vendor/bin/behat) to execute only the new scenario instead of running the whole set of tests.&lt;br /&gt;
# Add extra tags to the scenario or the feature if required according to https://docs.moodle.org/dev/Acceptance_testing#Tests_filters&lt;br /&gt;
&lt;br /&gt;
=== Available steps ===&lt;br /&gt;
&lt;br /&gt;
Moodle provides a interface to list and filter the steps you can use when writing features. You can access it through the Administration block, following &#039;&#039;&#039;Site Administration&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;Development&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;Acceptance testing&#039;&#039;&#039;. It allows filtering by keyword, by the Moodle component or by the type of step:&lt;br /&gt;
* Processes to set up the environment&lt;br /&gt;
* Actions that provokes an event&lt;br /&gt;
* Checkings to ensure the outcomes are the expected ones&lt;br /&gt;
&lt;br /&gt;
[[File:Acceptance_testing_UI_2.5.png]]&lt;br /&gt;
&lt;br /&gt;
* This interface only works on sites where Behat is installed. If you are using the local PHP server, for example, you can access it on that site at http://localhost:8000 (log in as admin/admin).&lt;br /&gt;
&lt;br /&gt;
=== Tips ===&lt;br /&gt;
* You can use a &#039;&#039;&#039;Background&#039;&#039;&#039; section before the &#039;&#039;&#039;Scenario&#039;&#039;&#039; sections, this steps will be executed before the steps of each scenario (http://docs.behat.org/guides/1.gherkin.html#backgrounds)&lt;br /&gt;
* You can use &#039;&#039;&#039;Scenario outlines&#039;&#039;&#039; if your scenarios are nearly the same and depends on a few vars; check out the link for an explicative example (http://docs.behat.org/guides/1.gherkin.html#scenario-outlines)&lt;br /&gt;
** If your scenario outline consists of many steps it may be useful to add a comment with the number of steps. If the the test fails behat will tell you in which step overall and you will have to divide by the number of steps of the scenario to know in which example. &lt;br /&gt;
* Is better to test the outcomes against the given data than against language strings, which are depending on the selected language.&lt;br /&gt;
* In case you need to interact with popup windows you need to switch to the window you want to interact with after opening it using the &#039;&#039;&#039;I switch to &amp;quot;popupwindowname&amp;quot; window&#039;&#039;&#039;, close it when you finish interacting with it and return to the main window using &#039;&#039;&#039;I switch to main window&#039;&#039;&#039;&lt;br /&gt;
* The format of the .feature files is YAML which finds out the data hierarchy from the indentation of it&#039;s elements, so be sure that the elements are correctly nested and the indentation is correct using spaces when necessary&lt;br /&gt;
&lt;br /&gt;
=== Providing values to steps ===&lt;br /&gt;
Most of the steps requires values, there are five methods to provide values to steps, the method depends on the step specification, you can know when a steps requires a value because you will see a drop down menu with a closed list of options that the step accepts as argument or an upper case string between double quotes, something like &#039;&#039;&#039;I press &amp;quot;BUTTON_STRING&amp;quot;&#039;&#039;&#039; or it ends with a &#039;&#039;&#039;:&#039;&#039;&#039; . The five methods are:&lt;br /&gt;
* &#039;&#039;&#039;A string/text&#039;&#039;&#039;; is the most common case, the texts are wrapped between double quotes (&amp;quot; character) you have to replace the info about the expected value for your value; for example something like &#039;&#039;&#039;I press &amp;quot;BUTTON_STRING&amp;quot;&#039;&#039;&#039; should become &#039;&#039;&#039;I press &amp;quot;Save and return to course&amp;quot;&#039;&#039;&#039;. If you want to add a string which contains a &amp;quot; character, you can escape it with \&amp;quot;, for example &#039;&#039;&#039;I fill the &amp;quot;Name&amp;quot; field with &amp;quot;Alan alias \&amp;quot;the legend\&amp;quot;&amp;quot;&#039;&#039;&#039;. You can identify this steps because they ends with &#039;&#039;&#039;_STRING&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;A number&#039;&#039;&#039;; some steps requires numbers as values, to be more specific an undetermined number of digits from 0 to 9 (Natural numbers + 0) you can identify them because the expected value info string ends with &#039;&#039;&#039;_NUMBER&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;A table&#039;&#039;&#039;; is a relation between values, the most common use of it is to fill forms. The steps which requires tables are easily identifiable because they finish with &#039;&#039;&#039;:&#039;&#039;&#039; The steps description gives info about what the table columns must contain, for example &#039;&#039;&#039;Fills a moodle form with field/value data&#039;&#039;&#039;. Here you don&#039;t need to escape the double quotes if you want to include them as part of the value.&lt;br /&gt;
* &#039;&#039;&#039;A field value&#039;&#039;&#039;; There are many different field types, if an argument requires a field value the expected value will depend on the field type:&lt;br /&gt;
** Text-based fields: It expects the text. This includes textareas, input type text, input type password...&lt;br /&gt;
** Checkbox: It expects 1 to check and for checked and &amp;quot;&amp;quot; to uncheck or for unchecked&lt;br /&gt;
** Select: It expects the option text or the option value. In case you interact with a multi-select you should specify the options separating them with commas. For example: &#039;&#039;&#039;option1, option2, option3&#039;&#039;&#039;&lt;br /&gt;
** Radio: The text of the radio option&lt;br /&gt;
* &#039;&#039;&#039;A selector&#039;&#039;&#039;; there are steps that can be used with different kinds of elements, for example &#039;&#039;&#039;I click on &amp;quot;User Name&amp;quot; &amp;quot;link&amp;quot;&#039;&#039;&#039; or &#039;&#039;&#039;I click on &amp;quot;User Name&amp;quot; &amp;quot;button&amp;quot;&#039;&#039;&#039; this is a closed list of elements, they always works together with another argument, where you specify the locator (eg. the link text in a link) In the &#039;Acceptance testing&#039; interface you can see a drop-down menu to select one of these options:&lt;br /&gt;
** field - for searching a field by its id, name, value or label&lt;br /&gt;
** link - for searching a link by its href, id, title, img alt or value&lt;br /&gt;
** button - for searching a button by its name, id, value, img alt or title&lt;br /&gt;
** link_or_button - for searching for both, links and buttons&lt;br /&gt;
** select - for searching a select field by its id, name or label&lt;br /&gt;
** checkbox - for searching a checkbox by its id, name, or label&lt;br /&gt;
** radio - for searching a radio button by its id, name, or label&lt;br /&gt;
** file - for searching a file input by its id, name, or label&lt;br /&gt;
** optgroup - for searching optgroup by its label&lt;br /&gt;
** option - for searching an option by its content&lt;br /&gt;
** dialogue - for searching a dialogue with the specified header text&lt;br /&gt;
** filemanager - for searching a filemanager by it&#039;s id or label&lt;br /&gt;
** block - for searching a Moodle block by it&#039;s English name or it&#039;s frankenstyle name&lt;br /&gt;
** region - for searching a Moodle page region with that id, in fact it works with all the page&#039;s ids&lt;br /&gt;
** table_row - for searching a table row which contains the specified text&lt;br /&gt;
** table - for searching a table by its id or caption&lt;br /&gt;
** fieldset - for searching a fieldset by it&#039;s id or legend&lt;br /&gt;
** css_element - for searching an element by its CSS selector&lt;br /&gt;
** xpath_element - for searching an element by its XPath&lt;br /&gt;
* &#039;&#039;&#039;A text selector&#039;&#039;&#039;; similar to a selector but those are the elements that returns an area of the DOM, they are useful in steps following the format &#039;&#039;&#039;... in the &amp;quot;Community finder&amp;quot; &amp;quot;block&amp;quot;&#039;&#039;&#039; where you are clicking or looking for some text inside a specific area. In the &#039;Acceptance testing&#039; interface you can see a drop-down menu to select one of these options:&lt;br /&gt;
** dialogue - for searching a dialogue with the specified header text&lt;br /&gt;
** block - for searching a Moodle block by it&#039;s English name or it&#039;s frankenstyle name&lt;br /&gt;
** region - for searching a Moodle page region with that id, in fact it works with all the page&#039;s ids&lt;br /&gt;
** table_row - for searching a table row which contains the specified text&lt;br /&gt;
** table - for searching a table by its id or caption&lt;br /&gt;
** fieldset - for searching a fieldset by it&#039;s id or legend&lt;br /&gt;
** css_element - for searching an element by its CSS selector&lt;br /&gt;
** xpath_element - for searching an element by its XPath&lt;br /&gt;
&lt;br /&gt;
==== Uploading files ====&lt;br /&gt;
Note than some tests requires files to be uploaded, in this case&lt;br /&gt;
* The &#039;&#039;&#039;I upload &amp;quot;FILEPATH_STRING&amp;quot; file to &amp;quot;FILEPICKER_FIELD_STRING&amp;quot; filepicker&#039;&#039;&#039; step can be used when located in the form page&lt;br /&gt;
* The file to upload should be included along with the Moodle codebase in COMPONENTNAME/tests/fixtures/*&lt;br /&gt;
* The file to upload is specified by it&#039;s path, which should be relative to the codebase root (&#039;&#039;&#039;lib/tests/fixtures/users.csv&#039;&#039;&#039; for example) &lt;br /&gt;
* &#039;&#039;&#039;/&#039;&#039;&#039; should be used as directory separator and the file names can not include this &#039;&#039;&#039;/&#039;&#039;&#039; character as all of them would be converted to the OS-dependant directory separator to maintain the compatibility with Windows systems.&lt;br /&gt;
* The scenarios that includes files uploading should be tagged using the &#039;&#039;&#039;@_file_upload&#039;&#039;&#039; tag&lt;br /&gt;
&lt;br /&gt;
==== Checking table values ====&lt;br /&gt;
You can check if specific value exists or not in a table row/column by using:&lt;br /&gt;
* Then &amp;quot;STRING_IN_ROW&amp;quot; row &amp;quot;COLUMN_HEADER&amp;quot; column of &amp;quot;TABLE_ID&amp;quot; table should contain &amp;quot;VALUE_TO_CHECK&amp;quot;&lt;br /&gt;
* Then the following should exist in the &amp;quot;TABLE_ID&amp;quot; table:&lt;br /&gt;
    | COLUMN_HEADER1 | COLUMN_HEADER2 |&lt;br /&gt;
    | VALUE_IN_ROW_1 | VALUE_IN_ROW_1 |&lt;br /&gt;
    | VALUE_IN_ROW_2 | VALUE_IN_ROW_2 |&lt;br /&gt;
&lt;br /&gt;
=== Fixtures ===&lt;br /&gt;
&lt;br /&gt;
As seen in [[https://docs.moodle.org/dev/Acceptance_testing#Examples examples]] Moodle provides a way to quickly set up the contextual data (courses, users, enrolments...) that you need to properly test scenarios, this can be done using one of the site templates (TODO) or creating entities in the background section (common for all the steps) or in the &amp;quot;Given&amp;quot; part of your scenario. Note that this steps can only be used to set up the contextual data required to test the feature but they don&#039;t test what they are doing; for example, the &amp;quot;Given the following &amp;quot;users&amp;quot; exists&amp;quot; is not testing that Moodle is able to create a user, but to test that a user can add a blog entry you might want to use this step. For further info, acceptance tests are supposed to be black-boxed tests (the tester don&#039;t know about the internals of the application) and this steps are using internal Moodle data generators instead of running all the steps required to create a user or to create a course, which speeds up the test execution. There are other features to test that all this elements can be properly created.&lt;br /&gt;
&lt;br /&gt;
==== Available elements ====&lt;br /&gt;
Most of the available elements can only be created in relation to other elements, to hide the complexity of the Moodle internals (references by contexts, ids...) the references can be done using more human-friendly mappings. &lt;br /&gt;
&lt;br /&gt;
The examples below shows how to add elements referencing other elements, there are required fields to reference the elements, other attributes will be filled with random data if they are not specified.&lt;br /&gt;
&lt;br /&gt;
* Course categories&lt;br /&gt;
** The required field is idnumber&lt;br /&gt;
** References between parent/children by their idnumber, using the &amp;quot;category&amp;quot; field&lt;br /&gt;
  Given the following &amp;quot;categories&amp;quot; exist:&lt;br /&gt;
    | name       | category | idnumber |&lt;br /&gt;
    | Category 1 | 0        | CAT1     |&lt;br /&gt;
    | Category 2 | CAT1     | CAT2     |&lt;br /&gt;
&lt;br /&gt;
* Courses&lt;br /&gt;
** The required field is shortname&lt;br /&gt;
** Uses the category idnumber as category reference&lt;br /&gt;
  Given the following &amp;quot;courses&amp;quot; exist:&lt;br /&gt;
    | fullname | shortname | category | format | &lt;br /&gt;
    | Course 1 | COURSE1   | CAT1     | topics |&lt;br /&gt;
    | Course 2 | COURSE2   | CAT2     |        |&lt;br /&gt;
&lt;br /&gt;
* Activities *(note that this step does not work with all kind of activities, only the ones that have data generators)*&lt;br /&gt;
** The required fields are activity, course and idnumber&lt;br /&gt;
** Uses activity to specify the activity type&lt;br /&gt;
** Uses the course shortname as course reference&lt;br /&gt;
** Other activity-dependant fields can be specified by it&#039;s field name&lt;br /&gt;
  Given the following &amp;quot;activities&amp;quot; exist:&lt;br /&gt;
    | activity | course | idnumber | name                 | intro                       |&lt;br /&gt;
    | assign   | C1     | assign1  | Test assignment name | Test assignment description |&lt;br /&gt;
    | data     | C1     | data1    | Test database name   | Test database description   |&lt;br /&gt;
&lt;br /&gt;
* Groups&lt;br /&gt;
** The required fields are course and idnumber&lt;br /&gt;
** Uses the course shortname as course reference&lt;br /&gt;
  Given the following &amp;quot;groups&amp;quot; exist:&lt;br /&gt;
    | name    | description | course  | idnumber |&lt;br /&gt;
    | Group 1 | Anything    | COURSE1 | GROUP1   |&lt;br /&gt;
&lt;br /&gt;
* Groupings&lt;br /&gt;
** The required fields are course and idnumber&lt;br /&gt;
** Uses the course shortname as course reference&lt;br /&gt;
  Given the following &amp;quot;groupings&amp;quot; exist:&lt;br /&gt;
    | name       | course  | idnumber  |&lt;br /&gt;
    | Grouping 1 | COURSE1 | GROUPING1 |&lt;br /&gt;
    | Grouping 2 | COURSE1 | GROUPING2 |&lt;br /&gt;
&lt;br /&gt;
* Users&lt;br /&gt;
** The required field is username (if password is not set username value will be used as password too)&lt;br /&gt;
  Given the following &amp;quot;users&amp;quot; exist:&lt;br /&gt;
    | username | email       | firstname | lastname |&lt;br /&gt;
    | testuser | asd@asd.com | Test      | User     |&lt;br /&gt;
&lt;br /&gt;
* Course enrolments&lt;br /&gt;
** The required fields are user, course and role&lt;br /&gt;
** Uses the course shortname as course reference&lt;br /&gt;
** Uses the user username as user reference&lt;br /&gt;
** Uses the role shortname as role reference&lt;br /&gt;
** Uses the enrolment name as enrol reference&lt;br /&gt;
  Given the following &amp;quot;course enrolments&amp;quot; exist:&lt;br /&gt;
    | user     | course  | role           | enrol  |&lt;br /&gt;
    | testuser | COURSE1 | editingteacher | manual |&lt;br /&gt;
&lt;br /&gt;
* Roles&lt;br /&gt;
** The required field is shortname&lt;br /&gt;
** Uses a one of the following roles as archetype: manager, coursecreator, editingteacher, teacher, student, guest, user and frontpage&lt;br /&gt;
  Given the following &amp;quot;roles&amp;quot; exist:&lt;br /&gt;
    | shortname | name          | description | archetype      |&lt;br /&gt;
    | custom1   | Custom Role 1 |             | editingteacher |&lt;br /&gt;
&lt;br /&gt;
* Role assigns&lt;br /&gt;
** The required fields are user, role, contextlevel and reference&lt;br /&gt;
** Uses the user username as user reference&lt;br /&gt;
** Uses the role shortname as role reference&lt;br /&gt;
** Uses contextlevel + reference to specify the context. See [[#Referencing_contexts]] for more info.&lt;br /&gt;
  Given the following &amp;quot;role assigns&amp;quot; exist:&lt;br /&gt;
    | user  | role           | contextlevel | reference |&lt;br /&gt;
    | user1 | manager        | System       |           |&lt;br /&gt;
    | user2 | editingteacher | Category     | CATEGORY1 |&lt;br /&gt;
    | user3 | editingteacher | Course       | COURSE1   |&lt;br /&gt;
&lt;br /&gt;
* System role assigns (deprecated in favour of role assigns, see item right above this one)&lt;br /&gt;
** The required fields are user and role&lt;br /&gt;
** Uses the user username as user reference&lt;br /&gt;
** Uses the role shortname as role reference&lt;br /&gt;
  Given the following &amp;quot;system role assigns&amp;quot; exist:&lt;br /&gt;
    | user     | role    |&lt;br /&gt;
    | testuser | manager |&lt;br /&gt;
&lt;br /&gt;
* Permission overrides&lt;br /&gt;
** The required fields are capability, permissions, role, and the contextlevel + it&#039;s reference&lt;br /&gt;
** Uses contextlevel + reference to specify the context. See [[#Referencing_contexts]] for more info.&lt;br /&gt;
  Given the following &amp;quot;permission overrides&amp;quot; exist:&lt;br /&gt;
    | capability            | permission | role           | contextlevel | reference |&lt;br /&gt;
    | mod/forum:editanypost | Allow      | student        | Course       | C1        |&lt;br /&gt;
    | mod/forum:replynews   | Prevent    | editingteacher | Course       | C1        |&lt;br /&gt;
    | mod/paquiro:sings     | Prohibit   | student        | System       |           |&lt;br /&gt;
&lt;br /&gt;
* Group members&lt;br /&gt;
** The required fields are user and group&lt;br /&gt;
** Uses the group idnumber as group reference&lt;br /&gt;
** Uses the user username as user reference&lt;br /&gt;
  Given the following &amp;quot;group members&amp;quot; exist:&lt;br /&gt;
    | user     | group  |&lt;br /&gt;
    | testuser | GROUP1 |&lt;br /&gt;
&lt;br /&gt;
* Grouping groups&lt;br /&gt;
** The required fields are grouping and group&lt;br /&gt;
** Uses the group idnumber as group reference&lt;br /&gt;
** Uses the grouping idnumber as grouping reference&lt;br /&gt;
  Given the following &amp;quot;grouping groups&amp;quot; exist:&lt;br /&gt;
    | grouping  | group  |&lt;br /&gt;
    | GROUPING1 | GROUP1 |&lt;br /&gt;
&lt;br /&gt;
* Cohorts&lt;br /&gt;
** The required field is idnumber&lt;br /&gt;
  Given the following &amp;quot;cohorts&amp;quot; exist:&lt;br /&gt;
    | name     | idnumber |&lt;br /&gt;
    | Cohort 1 | COHORT1  |&lt;br /&gt;
&lt;br /&gt;
==== Referencing contexts ====&lt;br /&gt;
&lt;br /&gt;
Moodle has different context levels, internally they have an identifier, but to reference them from steps we can use a more human way, using the level of the context (as specified below) and the reference, which will depend on the contextlevel we are using:&lt;br /&gt;
* contextlevel: &#039;&#039;&#039;System&#039;&#039;&#039;, &#039;&#039;&#039;User&#039;&#039;&#039;, &#039;&#039;&#039;Category&#039;&#039;&#039;, &#039;&#039;&#039;Course&#039;&#039;&#039; or &#039;&#039;&#039;Activity module&#039;&#039;&#039;&lt;br /&gt;
* reference:&lt;br /&gt;
** System: Nothing, just leave the the cell empty&lt;br /&gt;
** User: The user &#039;&#039;&#039;username&#039;&#039;&#039;&lt;br /&gt;
** Category: The category &#039;&#039;&#039;idnumber&#039;&#039;&#039;&lt;br /&gt;
** Course: The course &#039;&#039;&#039;shortname&#039;&#039;&#039;&lt;br /&gt;
** Activity module: The activity &#039;&#039;&#039;idnumber&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The data generators which makes use of these format are pointing to here.&lt;br /&gt;
&lt;br /&gt;
=== Features check list ===&lt;br /&gt;
* It&#039;s a new feature or a new scenario of an existing feature&lt;br /&gt;
* Is using the &#039;&#039;&#039;Background&#039;&#039;&#039; section or &#039;&#039;&#039;Scenario Outlines&#039;&#039;&#039; instead of duplicating steps (only when applicable)&lt;br /&gt;
* Are using the appropriate Moodle component tag according to https://docs.moodle.org/dev/Acceptance_testing#Tests_filters&lt;br /&gt;
* The user story of the feature includes a valid stakeholder and makes sense according to https://docs.moodle.org/dev/Acceptance_testing#Writing_features&lt;br /&gt;
* Covers both JS and non-JS environments&lt;br /&gt;
&lt;br /&gt;
== Adding steps definitions ==&lt;br /&gt;
&lt;br /&gt;
Each Moodle component and plugin (including 3rd party plugins) can add new steps definitions. If you are writing tests and you notice that you are repeating the same group of steps you might want to create a new step definition that allows you to substitute the group of steps for one single step, something like &#039;&#039;I add a forum post with &amp;quot;blablabla&amp;quot; as description&#039;&#039; for example; also you can create whole new steps using the APIs provided by Behat and Mink if what you need to do is not covered by any of the available steps.&lt;br /&gt;
&lt;br /&gt;
As commented in https://docs.moodle.org/dev/Acceptance_testing#Fixtures, this are black box tests, so we are not supposed to know about Moodle internals; translated to developer language it means don&#039;t use Moodle internals API calls, for example you should not try to cheat using a set_config() call, you should follow Moodle&#039;s user interface to reach the setting page and change it&#039;s value.&lt;br /&gt;
&lt;br /&gt;
=== Example ===&lt;br /&gt;
&lt;br /&gt;
You can use this example below or any of the existing steps definitions as a template.&lt;br /&gt;
&lt;br /&gt;
* auth/tests/behat/behat_auth.php&lt;br /&gt;
  class behat_auth extends behat_base {&lt;br /&gt;
      /**&lt;br /&gt;
       * Logs in the user. There should exist a user with the same value as username and password&lt;br /&gt;
       *&lt;br /&gt;
       * This second comment line will be not shown in the steps definitions list as it is only&lt;br /&gt;
       * reading the first line in the comment block.&lt;br /&gt;
       *&lt;br /&gt;
       * @Given /^I log in as &amp;quot;(?P&amp;lt;username_string&amp;gt;(?:[^&amp;quot;]|\\&amp;quot;)*)&amp;quot;$/&lt;br /&gt;
       */&lt;br /&gt;
      public function i_log_in_as($username) {&lt;br /&gt;
          return array(new Given(&#039;I am on homepage&#039;),&lt;br /&gt;
              new Given(&#039;I follow &amp;quot;&#039; . get_string(&#039;login&#039;) . &#039;&amp;quot;&#039;),&lt;br /&gt;
              new Given(&#039;I fill in &amp;quot;&#039; . get_string(&#039;username&#039;) . &#039;&amp;quot; with &amp;quot;&#039; . $this-&amp;gt;escape($username) . &#039;&amp;quot;&#039;),&lt;br /&gt;
              new Given(&#039;I fill in &amp;quot;&#039; . get_string(&#039;password&#039;) . &#039;&amp;quot; with &amp;quot;&#039;. $this-&amp;gt;escape($username) . &#039;&amp;quot;&#039;),&lt;br /&gt;
              new Given(&#039;I press &amp;quot;&#039; . get_string(&#039;login&#039;) . &#039;&amp;quot;&#039;)&lt;br /&gt;
          );&lt;br /&gt;
      }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
=== Tips ===&lt;br /&gt;
&lt;br /&gt;
If you are creating a completely new step definition there are also a few things to consider:&lt;br /&gt;
* Steps definitions should be compatible with both Javascript and non-Javascript tests, you can use $this-&amp;gt;running_javascript() to deal with both&lt;br /&gt;
* The definition code will be executed by Behat, not by Moodle, you have to keep this in mind for example when throwing exceptions, Behat exceptions will give more info to the user about where is the problem&lt;br /&gt;
** You can find these exceptions in &#039;&#039;&#039;vendor/behat/mink/src/Behat/Mink/Exception/*&#039;&#039;&#039;&lt;br /&gt;
* Selenium is fast, sometimes it tries to interact with DOM elements or tries to execute actions that requires JS that are not loaded or ready to used; this is why, sometimes and randomly, you can see an &amp;quot;element not found&amp;quot; failure&lt;br /&gt;
** The quickest way to solve this problem is using behat_base::find*() methods (where the * corresponds to &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;&#039;&#039;&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;, &#039;&#039;&#039;_all&#039;&#039;&#039;, or to a named selector preceded by &#039;&#039;&#039;_&#039;&#039;&#039;, http://mink.behat.org/#named-selectors) which only requires the locator as argument. This methods will wait for the requested element to be ready or return an exception if the element is not found after the timeout value expires, you can also force the timeout value, which defaults to 6 seconds. An example of a named selector use is &#039;&#039;&#039;$button = $this-&amp;gt;find_button(&amp;quot;Save changes&amp;quot;);&#039;&#039;&#039; if you are not sure about the element being available you always can wrap the find*() call in a try &amp;amp; catch.&lt;br /&gt;
** For advanced usages, the spin method is defined in &#039;&#039;&#039;lib/behat/behat_base::spin&#039;&#039;&#039;, consider that all the contents of the closures passed to spin() can be executed more than once, so don&#039;t use irreversible actions that can invalidate the tests results (for example use find() methods but don&#039;t use click() methods)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you create new steps definitions or tests you must run &#039;&#039;&#039;php admin/tool/behat/cli/util.php --enable&#039;&#039;&#039; to update the Behat config file before running &#039;&#039;&#039;vendor/bin/behat&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Check list ===&lt;br /&gt;
&lt;br /&gt;
New steps should be/have:&lt;br /&gt;
* Implemented as public methods of a PHP class whose name must begin with &#039;behat_&#039; prefix and with &#039;.php extension&lt;br /&gt;
* Using the class name as filename (adding the &#039;.php&#039; extension) and extending MOODLEDIRROOT/lib/behat/behat_base.php (or MOODLEDIRROOT/lib/behat/behat_files.php if it&#039;s a repository or is files-related)&lt;br /&gt;
* With a descriptive class name, for example the component name (it will be used when filtering steps definitions)&lt;br /&gt;
* Stored in COMPONENTNAME/tests/behat/ directory or lib/tests/behat/ if is not part of any other component&lt;br /&gt;
* Describe it&#039;s purpose in a single line inside the method doc comment, the size of the comment is not a problem&lt;br /&gt;
* Describe the regular expression with the most appropriate tag inside the method doc comment:&lt;br /&gt;
** &#039;&#039;&#039;@Given&#039;&#039;&#039; - A step to set up the initial context (for example &#039;&#039;the following &amp;quot;courses&amp;quot; exists&#039;&#039;)&lt;br /&gt;
** &#039;&#039;&#039;@When&#039;&#039;&#039; - An action that provokes an event (for example &#039;&#039;I press the button &amp;quot;buttonname&amp;quot;&#039;&#039;)&lt;br /&gt;
** &#039;&#039;&#039;@Then&#039;&#039;&#039; - Checkings to ensure the outcomes are the expected (for example &#039;&#039;I should see &amp;quot;whatever&amp;quot;&#039;&#039;)&lt;br /&gt;
* Depending on the inputs your definition expects you must use a different regular expression:&lt;br /&gt;
** &#039;&#039;&#039;If you expect a number:&#039;&#039;&#039; &amp;quot;(?P&amp;lt;info_about_what_you_expect_number&amp;gt;\d+)&amp;quot; (note that the regular expression is quoted between &#039;&#039;&#039;&amp;quot;&#039;&#039;&#039;)&lt;br /&gt;
** &#039;&#039;&#039;If you expect a string or a text:&#039;&#039;&#039; &amp;quot;(?P&amp;lt;info_about_what_you_expect_string&amp;gt;(?:[^&amp;quot;]|\\&amp;quot;)*)&amp;quot; Don&#039;t use &#039;&#039;&#039;text_selector_string&#039;&#039;&#039; and &#039;&#039;&#039;selector_string&#039;&#039;&#039; as info strings, they are reserved to selector types (note that the regular expression is quoted between &#039;&#039;&#039;&amp;quot;&#039;&#039;&#039;)&lt;br /&gt;
** &#039;&#039;&#039;If you expect a table with key/value pairs (for example to fill a form):&#039;&#039;&#039; Finish your regular expression with &#039;&#039;&#039;:&#039;&#039;&#039; and provide info in the description about the contents of the table&lt;br /&gt;
** &#039;&#039;&#039;If you expect a selector type:&#039;&#039;&#039; &amp;quot;(?P&amp;lt;selector_string&amp;gt;[^&amp;quot;]*)&amp;quot; or &amp;quot;(?P&amp;lt;text_selector_string&amp;gt;[^&amp;quot;]*)&amp;quot; depending on whether you want to use any selector or you want a text-based selector (more info about selectors in https://docs.moodle.org/dev/Acceptance_testing#Providing_values_to_steps)&lt;br /&gt;
* To make test writer&#039;s life better is good to include explicative info in the subexpressions of the regular expression about what the test writer is supposed to put in there (for example &#039;&#039;I expand &amp;quot;(?P&amp;lt;nodetext&amp;gt;(?:[^&amp;quot;]|\\&amp;quot;)*)&amp;quot; node&#039;&#039;)&lt;br /&gt;
* Is recommended to use the static part of the regular expression as the name of the method, using underscores instead of spaces (see current steps definitions)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== How can you tell if Selenium is running? ===&lt;br /&gt;
&lt;br /&gt;
Try going to http://localhost:4444/selenium-server/. If Selenium is not running, nothing will happen. You will get a time-out. If selenium is running, you will get a 404 error page saying powered by Jetty at the bottom.&lt;br /&gt;
&lt;br /&gt;
=== How can I stop Selenium? ===&lt;br /&gt;
&lt;br /&gt;
Go to the URL http://localhost:4444/selenium-server/driver/?cmd=shutDownSeleniumServer. I think when it works it outputs &amp;quot;OKOK&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Behat tells me that lots of steps are undefined ===&lt;br /&gt;
&lt;br /&gt;
You probably forgot the --config option in the behat command.&lt;br /&gt;
&lt;br /&gt;
== Browser specific fixes ==&lt;br /&gt;
&lt;br /&gt;
If you are interested in running behat in other browsers you might be interested on https://docs.moodle.org/dev/Acceptance_testing/Browsers&lt;br /&gt;
&lt;br /&gt;
When running acceptance tests in conjunction with Selenium against Chrome, IE, or Safari there is a fix for the navigation bar that gets applied in order to avoid errors arising from a bug in the webdrivers for those browsers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;The issue&amp;lt;/b&amp;gt;: When an acceptance test goes to interact with an element on the page it first ensures that the element in the view-port and if not scrolls the browser to get the element into the view-port. If you are running against Chrome, IE, or Safari the browser scrolls the element only just inside the view-port. It doesn&#039;t however allow for any fixed position elements such as the navigation bar.&lt;br /&gt;
What happens: In some situations these browsers scroll up to reach a button, however not enough as the button ends up behind the navigation bar and cannot be interacted with.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Our solution&amp;lt;/b&amp;gt;: We can not change browser driver behaviour so we have integrated a work around. When running acceptance tests against one of these browsers we change the position attribute of the navigation bar from fixed to absolute. This is not ideal as it is not how the user experiences the site, however it allows us to run the full acceptance test suite against these browsers so we allowed it. A notice will be displayed when you start an acceptance test run if the browser specific fixes have been applied. See MDL-47734 / MDL-45231 for more details.&lt;br /&gt;
&lt;br /&gt;
== See also == &lt;br /&gt;
&lt;br /&gt;
* Guidelines for contributors: [[Acceptance_testing/Contributing_automated_tests|Contributing automated tests]]&lt;br /&gt;
* Technical info: [[Behat integration]]&lt;br /&gt;
* Behat CLI command options: http://docs.behat.org/guides/6.cli.html&lt;br /&gt;
* How to use selectors to interact with the site elements: http://mink.behat.org/#traverse-the-page-selectors&lt;br /&gt;
[[Category:Behat]][[Category:Quality Assurance]]&lt;br /&gt;
&lt;br /&gt;
[[es:Prueba de aceptación]]&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Hackfest_UK_2014&amp;diff=45315</id>
		<title>Hackfest UK 2014</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Hackfest_UK_2014&amp;diff=45315"/>
		<updated>2014-06-16T09:39:18Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: /* HTML5 Player */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[file:Hackfest_Logo_-_Narrow.png|202|right]]&lt;br /&gt;
&lt;br /&gt;
[[Developer meetings]] &amp;gt; UK Hackfest April 2014&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| When&lt;br /&gt;
| Thursday 17 April, 2014&lt;br /&gt;
|-&lt;br /&gt;
| Where&lt;br /&gt;
| Moodlemoot Edinburgh, UK&lt;br /&gt;
|-&lt;br /&gt;
| Hashtag&lt;br /&gt;
| [https://twitter.com/search/%23mootuk14 #mootuk14]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== What happened? ==&lt;br /&gt;
&lt;br /&gt;
A Hackfest brings together Moodle developers to brainstorm future Moodle developments.&lt;br /&gt;
&lt;br /&gt;
This hackfest had a group of around 40 developers.  We met in Edinburgh on 17th April 2014 to discuss a range of topics (decided by the participants in unconference fashion), with the aim to distil knowledge into some blueprints for specifications of future Moodle features.&lt;br /&gt;
&lt;br /&gt;
== Specifications ==&lt;br /&gt;
&lt;br /&gt;
Specifications from subsequent work will be linked from here.&lt;br /&gt;
&lt;br /&gt;
=== Element Library ===&lt;br /&gt;
* [[Render_library_specification|Specification]]&lt;br /&gt;
* [https://docs.google.com/document/d/1iisKZks8e_JqjpGTXip1dJ9hS29QsGG4mSomKcFGVRg/edit?usp=sharing Notes taken during Hackfest]&lt;br /&gt;
* Links&lt;br /&gt;
** [http://tracker.moodle.org/browse/MDL-36558 Tracker issue]&lt;br /&gt;
** [https://github.com/totara/moodle/tree/mdl-feature-element-library Example]&lt;br /&gt;
** [https://moodle.org/mod/forum/discuss.php?d=215807 Forum discussion]&lt;br /&gt;
&lt;br /&gt;
=== Analytics ===&lt;br /&gt;
* [[Report_Builder_Specification|Specification]]&lt;br /&gt;
*[https://docs.google.com/document/d/1mlJjxewBOaZyQ14C0KIe5aV38hCmWF5aIQldlw-EwmU/edit?usp=sharing Notes taken during Hackfest]&lt;br /&gt;
&lt;br /&gt;
=== LTI Usability Improvements ===&lt;br /&gt;
* [[LTI Usability Improvements|Specification]]&lt;br /&gt;
* [[Hackfest_UK_2014/LTI|Notes taken during Hackfest]] (Is this the start of a spec?)&lt;br /&gt;
&lt;br /&gt;
=== Lesson activity module reboot ===&lt;br /&gt;
* [[Lesson activity module 2|Specification]]&lt;br /&gt;
* [https://docs.google.com/document/d/1XjiVY3ax9EuZ7gneofJR9z330rdI9bhD0yoOzt5tYRY/edit?usp=sharing Notes taken during Hackfest]&lt;br /&gt;
&lt;br /&gt;
=== Email Logging and Reporting ===&lt;br /&gt;
* [[Email Logging and Reporting|Specification]]&lt;br /&gt;
* [[Hackfest_UK_2014/Email Logging|Notes taken during Hackfest]] (Is this the start of a spec?)&lt;br /&gt;
&lt;br /&gt;
=== Bootstrap3 ===&lt;br /&gt;
* [[Bootstrap3|Specification]]&lt;br /&gt;
* [[Hackfest_UK_2014/Bootstrap3|Notes taken during Hackfest]] (Is this the start of a spec?)&lt;br /&gt;
&lt;br /&gt;
=== HTML5 Player ===&lt;br /&gt;
* [https://docs.moodle.org/dev/HTML5_player Specification]&lt;br /&gt;
* [https://docs.google.com/document/d/11uOmoQdxZAy3dh-BHs7pkFFHyoUlQ8PD2SdxuhlDsK0/edit Notes taken during Hackfest]&lt;br /&gt;
&lt;br /&gt;
=== Drag and Drop activities ===&lt;br /&gt;
* [[Drag and Drop activities|Specification]]&lt;br /&gt;
* [https://docs.google.com/document/d/15hme5Ky_YVQzks78HjDt8-kmZ3sT71WI4a_AK2LkSc8/edit Notes taken during Hackfest]&lt;br /&gt;
&lt;br /&gt;
=== Add-ons Trust Model ===&lt;br /&gt;
* [[Add-ons trust model|Specification]] (This was more of an advisory brainstorm, perhaps a spec is not necessary.)&lt;br /&gt;
* [https://docs.google.com/document/d/1GTbTLHMfqMvB1N-lEDx_AybYRyN8M-RqIFjp5QDNLkk/edit Notes taken during Hackfest]&lt;br /&gt;
&lt;br /&gt;
==Tools==&lt;br /&gt;
&lt;br /&gt;
During the Hackfest, there was a session where developers named tools they were using. If you haven&#039;t heard of the tools below, you might want to check them out.&lt;br /&gt;
&lt;br /&gt;
* PHP Xref&lt;br /&gt;
* Xdebug + IDE&lt;br /&gt;
* XHprof&lt;br /&gt;
* Code checker plugin&lt;br /&gt;
* PHPUnit&lt;br /&gt;
* MDK&lt;br /&gt;
* Moosh&lt;br /&gt;
* Grunt&lt;br /&gt;
* Git&lt;br /&gt;
&lt;br /&gt;
== Other suggested topics ==&lt;br /&gt;
&lt;br /&gt;
These are topics that were suggested, but were not chosen for sessions (unconference style), but may be worth future consideration.&lt;br /&gt;
* MUC best practice discussion&lt;br /&gt;
* Converter for Word docs to pages (possibly with drag-and-drop)&lt;br /&gt;
* Student &amp;gt; Group &amp;gt; Course &amp;gt; Qualification &amp;gt; Body hierarchy&lt;br /&gt;
* Internal verification and validation&lt;br /&gt;
* Course reset for blocks and local plugins&lt;br /&gt;
* RTL CSS as a separate file&lt;br /&gt;
* Global change data recorded on database tables&lt;br /&gt;
* In course search&lt;br /&gt;
* Resource tagging / Index&lt;br /&gt;
* Sharepoint integration repository&lt;br /&gt;
* Scheduled fileless backups&lt;br /&gt;
* How the OU does &amp;quot;View as student&amp;quot;&lt;br /&gt;
* Better way to hide activities, but have them available&lt;br /&gt;
* All communication via messaging sends multi-part emails&lt;br /&gt;
* &amp;quot;Safe&amp;quot; group membership upload/import&lt;br /&gt;
* Facebook style &amp;quot;Like&amp;quot; button or + and - buttons for ratings (MDL-45394)&lt;br /&gt;
* Blind marking issues for administrative users&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Hackfest_UK_2014&amp;diff=44721</id>
		<title>Hackfest UK 2014</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Hackfest_UK_2014&amp;diff=44721"/>
		<updated>2014-05-09T08:37:26Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: Add tracker link for &amp;quot;Facebook style Like button&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[file:Hackfest_Logo_-_Narrow.png|202|right]]&lt;br /&gt;
&lt;br /&gt;
[[Developer meetings]] &amp;gt; UK Hackfest April 2014&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| When&lt;br /&gt;
| Thursday 17 April, 2014&lt;br /&gt;
|-&lt;br /&gt;
| Where&lt;br /&gt;
| Moodlemoot Edinburgh, UK&lt;br /&gt;
|-&lt;br /&gt;
| Hashtag&lt;br /&gt;
| [https://twitter.com/search/%23mootuk14 #mootuk14]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== What happened? ==&lt;br /&gt;
&lt;br /&gt;
A Hackfest brings together Moodle developers to brainstorm future Moodle developments.&lt;br /&gt;
&lt;br /&gt;
This hackfest had a group of around 40 developers.  We met in Edinburgh on 17th April 2014 to discuss a range of topics (decided by the participants in unconference fashion), with the aim to distil knowledge into some blueprints for specifications of future Moodle features.&lt;br /&gt;
&lt;br /&gt;
== Specifications ==&lt;br /&gt;
&lt;br /&gt;
Specifications from subsequent work will be linked from here.&lt;br /&gt;
&lt;br /&gt;
=== Element Library ===&lt;br /&gt;
* [[Element library|Specification]]&lt;br /&gt;
* [https://docs.google.com/document/d/1iisKZks8e_JqjpGTXip1dJ9hS29QsGG4mSomKcFGVRg/edit?usp=sharing Notes taken during Hackfest]&lt;br /&gt;
* Links&lt;br /&gt;
** [http://tracker.moodle.org/browse/MDL-36558 Tracker issue]&lt;br /&gt;
** [https://github.com/totara/moodle/tree/mdl-feature-element-library Example]&lt;br /&gt;
** [https://moodle.org/mod/forum/discuss.php?d=215807 Forum discussion]&lt;br /&gt;
&lt;br /&gt;
=== Analytics ===&lt;br /&gt;
* [[Analytics|Specification]]&lt;br /&gt;
*[https://docs.google.com/document/d/1mlJjxewBOaZyQ14C0KIe5aV38hCmWF5aIQldlw-EwmU/edit?usp=sharing Notes taken during Hackfest]&lt;br /&gt;
&lt;br /&gt;
=== LTI Usability Improvements ===&lt;br /&gt;
* [[LTI Usability Improvements|Specification]]&lt;br /&gt;
* [[Hackfest_UK_2014/LTI|Notes taken during Hackfest]] (Is this the start of a spec?)&lt;br /&gt;
&lt;br /&gt;
=== Lesson activity module reboot ===&lt;br /&gt;
* [[Lesson activity module 2|Specification]]&lt;br /&gt;
* [https://docs.google.com/document/d/1XjiVY3ax9EuZ7gneofJR9z330rdI9bhD0yoOzt5tYRY/edit?usp=sharing Notes taken during Hackfest]&lt;br /&gt;
&lt;br /&gt;
=== Email Logging and Reporting ===&lt;br /&gt;
* [[Email Logging and Reporting|Specification]]&lt;br /&gt;
* [[Hackfest_UK_2014/Email Logging|Notes taken during Hackfest]] (Is this the start of a spec?)&lt;br /&gt;
&lt;br /&gt;
=== Bootstrap3 ===&lt;br /&gt;
* [[Bootstrap3|Specification]]&lt;br /&gt;
* [[Hackfest_UK_2014/Bootstrap3|Notes taken during Hackfest]] (Is this the start of a spec?)&lt;br /&gt;
&lt;br /&gt;
=== HTML5 Player ===&lt;br /&gt;
* [[HTML5 Player|Specification]]&lt;br /&gt;
* [https://docs.google.com/document/d/11uOmoQdxZAy3dh-BHs7pkFFHyoUlQ8PD2SdxuhlDsK0/edit Notes taken during Hackfest]&lt;br /&gt;
&lt;br /&gt;
=== Drag and Drop activities ===&lt;br /&gt;
* [[Drag and Drop activities|Specification]]&lt;br /&gt;
* [https://docs.google.com/document/d/15hme5Ky_YVQzks78HjDt8-kmZ3sT71WI4a_AK2LkSc8/edit Notes taken during Hackfest]&lt;br /&gt;
&lt;br /&gt;
=== Add-ons Trust Model ===&lt;br /&gt;
* [[Add-ons trust model|Specification]] (This was more of an advisory brainstorm, perhaps a spec is not necessary.)&lt;br /&gt;
* [https://docs.google.com/document/d/1GTbTLHMfqMvB1N-lEDx_AybYRyN8M-RqIFjp5QDNLkk/edit Notes taken during Hackfest]&lt;br /&gt;
&lt;br /&gt;
==Tools==&lt;br /&gt;
&lt;br /&gt;
During the Hackfest, there was a session where developers named tools they were using. If you haven&#039;t heard of the tools below, you might want to check them out.&lt;br /&gt;
&lt;br /&gt;
* PHP Xref&lt;br /&gt;
* Xdebug + IDE&lt;br /&gt;
* XHprof&lt;br /&gt;
* Code checker plugin&lt;br /&gt;
* PHPUnit&lt;br /&gt;
* MDK&lt;br /&gt;
* Moosh&lt;br /&gt;
* Grunt&lt;br /&gt;
* Git&lt;br /&gt;
&lt;br /&gt;
== Other suggested topics ==&lt;br /&gt;
&lt;br /&gt;
These are topics that were suggested, but were not chosen for sessions (unconference style), but may be worth future consideration.&lt;br /&gt;
* MUC best practice discussion&lt;br /&gt;
* Converter for Word docs to pages (possibly with drag-and-drop)&lt;br /&gt;
* Student &amp;gt; Group &amp;gt; Course &amp;gt; Qualification &amp;gt; Body hierarchy&lt;br /&gt;
* Internal verification and validation&lt;br /&gt;
* Course reset for blocks and local plugins&lt;br /&gt;
* RTL CSS as a separate file&lt;br /&gt;
* Global change data recorded on database tables&lt;br /&gt;
* In course search&lt;br /&gt;
* Resource tagging / Index&lt;br /&gt;
* Sharepoint integration repository&lt;br /&gt;
* Scheduled fileless backups&lt;br /&gt;
* How the OU does &amp;quot;View as student&amp;quot;&lt;br /&gt;
* Better way to hide activities, but have them available&lt;br /&gt;
* All communication via messaging sends multi-part emails&lt;br /&gt;
* &amp;quot;Safe&amp;quot; group membership upload/import&lt;br /&gt;
* Facebook style &amp;quot;Like&amp;quot; button or + and - buttons for ratings (MDL-45394)&lt;br /&gt;
* Blind marking issues for administrative users&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=44491</id>
		<title>HTML5 player</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=44491"/>
		<updated>2014-04-17T22:22:32Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: /* Comparison Matrix */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}&lt;br /&gt;
{{Infobox Project&lt;br /&gt;
|name = HTML5 Player with flash fallback&lt;br /&gt;
|state = In Development&lt;br /&gt;
|tracker = https://tracker.moodle.org/browse/MDL-38158&lt;br /&gt;
|discussion = https://moodle.org/mod/forum/discuss.php?d=222753#p1110024&lt;br /&gt;
|assignee = [https://tracker.moodle.org/secure/ViewProfile.jspa?name=kabalin Ruslan Kabalin]&lt;br /&gt;
}}&lt;br /&gt;
{{Moodle 2.x}}&lt;br /&gt;
&lt;br /&gt;
== Project goals ==&lt;br /&gt;
&lt;br /&gt;
The purpose of this document is to choose HTML5 player with flash fallback for integration in Moodle and plan its implementation.&lt;br /&gt;
&lt;br /&gt;
The aim of this change is to reach a consistent look of the player among different platforms and browsers, as well as making sure that player starts using flash if html5 is not supported by browser for the given format. Another aim is to improve accessibility and usability, enhance customisation.&lt;br /&gt;
&lt;br /&gt;
== Considerations ==&lt;br /&gt;
&lt;br /&gt;
* Usability of the player - is it easy to use it and intuitively understand how to use controls?&lt;br /&gt;
* Accessibility of the player - possibility of keyboard navigation, subtitles, support?&lt;br /&gt;
* Appearance of the player - can its interface be modified, themes support, RTL?&lt;br /&gt;
* Consistency among browsers - does player look the same?&lt;br /&gt;
* Audio support - can player handle HTML5 &amp;lt;audio&amp;gt; tag?&lt;br /&gt;
* Mobile platforms support - does player also work on iOS and Android?&lt;br /&gt;
* Streaming media support (including adaptive-bitrate delivery) - can player handle RTMP, Apple HLS, Adobe HDS, Microsoft HSS?&lt;br /&gt;
* Plugins support - can we use or develop community plugins easily?&lt;br /&gt;
* Embedding support - so users could post media content outside Moodle, if permitted.&lt;br /&gt;
* Maintainability of the links between the player and Moodle - how much work will we need to do every time we upgrade?&lt;br /&gt;
&lt;br /&gt;
== Candidates ==&lt;br /&gt;
&lt;br /&gt;
* [http://flowplayer.org/ Flowplayer HTML5]&lt;br /&gt;
* [http://www.videojs.com/ Video.JS]&lt;br /&gt;
* [http://www.projekktor.com/ Projekktor]&lt;br /&gt;
* ?Are there other alternatives?&lt;br /&gt;
&lt;br /&gt;
== Comparison Matrix ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! [[#Flowplayer_HTML5|Flowplayer HTML5]]&lt;br /&gt;
! [[#Video.JS|Video.JS]]&lt;br /&gt;
! [[#Projekktor|Projekktor]]&lt;br /&gt;
! No Player&lt;br /&gt;
|-&lt;br /&gt;
! Accessible Player:&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Keyboard control&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes (configurable)&lt;br /&gt;
| unknown&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Subtitles support&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via plugin)&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Touch interface&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Appearance:&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Skins&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* CSS customisation&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| unknown&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTL support&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| No&lt;br /&gt;
| Unknown&lt;br /&gt;
|-&lt;br /&gt;
! Mobile platforms:&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* iOS&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Android&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Streaming protocols:&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTMP&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via playlist)&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Adaptive HTTP&lt;br /&gt;
| HLS&lt;br /&gt;
| HLS (via plugin)&lt;br /&gt;
| HLS (via playlist)&lt;br /&gt;
| Only in Chrome so far (Media Source Extension)&lt;br /&gt;
|-&lt;br /&gt;
! Audio player&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Embedding support&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (configurable)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via addThis plugin)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via plugin)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | No&lt;br /&gt;
|-&lt;br /&gt;
! License&lt;br /&gt;
| GPL v3 (with additional terms)&lt;br /&gt;
| Apache 2&lt;br /&gt;
| GPL v3&lt;br /&gt;
| no extra code needed&lt;br /&gt;
|-&lt;br /&gt;
! JS library&lt;br /&gt;
| jQuery&lt;br /&gt;
| -&lt;br /&gt;
| jQuery&lt;br /&gt;
| none required&lt;br /&gt;
|-&lt;br /&gt;
! Plugins infrastructure&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
! Flash fallback player&lt;br /&gt;
| Flowplayer Flash&lt;br /&gt;
| video-js flash&lt;br /&gt;
| StobeMediaPlayback (but can be jarisplayer or some other).&lt;br /&gt;
| VideoForEverybody can allow you to use any Flash player as fallback.&lt;br /&gt;
|-&lt;br /&gt;
! API&lt;br /&gt;
| Yes (plus window.flowplayer object)&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Flowplayer HTML5 ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* Good looking player, resembles existing flash flowplayer in Moodle (with &amp;quot;functional&amp;quot; skin)&lt;br /&gt;
* Extensive customisation (via CSS3 skins and configuration object)&lt;br /&gt;
* Streaming support (RTMP, HLS)&lt;br /&gt;
* Good accessibility features&lt;br /&gt;
* Configurable embedding functionality&lt;br /&gt;
* Existing flash flowplayer can be configured for fallback (the appearance of player will not be affected).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Require jQuery for functioning&lt;br /&gt;
* Flowplayer logo remains on screen&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using wrapper around &amp;lt;video&amp;gt;.&lt;br /&gt;
* width and height attributes in video tag are ignored, player size is configured via wrapper size only.&lt;br /&gt;
* RTMP server connection is configured via data-rtmp attribute in wrapper or player init config parameter, actual path the file specified in src attribute of source item.&lt;br /&gt;
* &amp;lt;source type=&amp;quot;video/flash&amp;quot;... dummy MIME type to force using plash player for whatever content.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Plugins infrastructure&lt;br /&gt;
* No audio support&lt;br /&gt;
&lt;br /&gt;
=== Video.JS ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Extensive API.&lt;br /&gt;
* No extra JS library needed.&lt;br /&gt;
* Many plugins.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Poor documentation&lt;br /&gt;
* RTMP requires non-standard MIME.&lt;br /&gt;
* Android and iOS override Video.JS with own player, when not overridden, content is not playing.&lt;br /&gt;
* No RTL.&lt;br /&gt;
* HLS support via plugin (many files to include, external contributor see https://github.com/videojs/videojs-contrib-hls).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* RTMP server connection and path specified as single URI in src attribute of source item, &#039;&amp;amp;&#039; character is used as server connection and path divider.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Embedded HLS support.&lt;br /&gt;
&lt;br /&gt;
=== Projekktor ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Well documented API.&lt;br /&gt;
* Media RSS support.&lt;br /&gt;
* Possibility to choose flash player for fallback (included by default are StrobeMediaPlayback and Jarisplayer, both Open Source).&lt;br /&gt;
* Platform preference order selection (e.g. browser, ios, android, flash, native).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Uses flash where it is not supposed to (e.g. mp4 in Chrome).&lt;br /&gt;
* Issues on ios and android (suggests to download file when play button is pressed).&lt;br /&gt;
* RTMP only work if defined via playlist rather than in &amp;lt;source&amp;gt; tags.&lt;br /&gt;
* Subtitles plugin is not free.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* Make sure &amp;lt;video&amp;gt; tag has class attribute with &#039;projekktor&#039; value (even if you initialise it by ID of the element), player will not work properly otherwise.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== HTML5 browser native ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* Simple&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* IE8 has no support&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes&#039;&#039;&#039;&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Cross-browser support ==&lt;br /&gt;
&lt;br /&gt;
=== Method ===&lt;br /&gt;
Compatibility checks were done manually by accessing the sample page using different browsers and platforms. Sample page contained the list of identical player instances, initialised for each &amp;lt;video&amp;gt; definition with a &amp;lt;source&amp;gt; of particular format: mp4, webm, ogg, flv. Streaming support was checked by setting up a &amp;lt;video&amp;gt; container with two sources of the same video, one was HLS (Apple HTTP Live Streaming) stream for browsers and platforms that support html5 video streaming, another one was RTMP which is played using flash engine and supposed to be used in case if HLS is not supported.&lt;br /&gt;
&lt;br /&gt;
=== Sample Pages ===&lt;br /&gt;
&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=flowplayer Flowplayer HTML5] version 5.4.6.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=videojs Video.JS] version 4.4.1.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=projekktor Projekktor] version 1.3.09.&lt;br /&gt;
&lt;br /&gt;
=== Source ===&lt;br /&gt;
&lt;br /&gt;
Source of testing page is hosted on [https://github.com/kabalin/test-html5-players/blob/master/players.php github]. The actual source of the html page can be viewed in browser.&lt;br /&gt;
&lt;br /&gt;
=== Discussion ===&lt;br /&gt;
&lt;br /&gt;
The players comparison that has been carried out demonstrated that &amp;quot;least hassle&amp;quot; player is Flowplayer. Despite some drawbacks listed in [[#Flowplayer_HTML5|corresponding section above]], it is clearly a winner as it works as expected and according to documentation for all browsers and platforms I had chance to test it. This is the only player that supports RTL layout, display platform incompatibility message prior to attempt to play, and was simple to configure (no undocumented tricks that I had to figure out to make it work). Both VideoJS and Projekktor do now perform properly in all cases. Among those two, I personally prefer Projekktor more for its extensive API, plugins infrastructure and configuration flexibility. However problems on mobile platforms and flash fallback inconsistency make them unreliable at this stage.&lt;br /&gt;
&lt;br /&gt;
=== Compatibility results ===&lt;br /&gt;
&lt;br /&gt;
The table was populated using Flowplayer as others do not perform good enough with some formats and platforms, e.g. VideoJS allow mobile platform player to override itself, Projekktor does not always use HTML5 where browser clearly can handle it (supported in native mode and Flowplayer).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Browser&lt;br /&gt;
! mp4&lt;br /&gt;
! webm&lt;br /&gt;
! ogg&lt;br /&gt;
! flv&lt;br /&gt;
! RTMP/HLS*&lt;br /&gt;
|-&lt;br /&gt;
! Windows 7&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Firefox 27.0.1&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 12.16&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 5.1.7&lt;br /&gt;
| flash&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Internet Explorer 11.0.9600.x&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Linux (Debian Wheezy)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.115&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! OSX 10.9&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 7.0 (9537.71)&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 phone (CyanogenMod, no flash)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 tablet (GalaxyTab2, flash app 11.1.115.36)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 19.0.1340.x&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
! iPhone 4S (6.1.3)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! iPad 4 (7.0.6)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;small&amp;gt;* For HLS/RTMP, html5 in the table means HLS has been used, flash means player fell back and used RTMP.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sub Tasks ==&lt;br /&gt;
&lt;br /&gt;
In initial stage FlowPlayer HTML5 (or any other) will handle all existing HTML5 Video extensions as per core_media_player_html5video class, plus m3u8 (HLS). It will also be possible optionally to make flash files handled by HTML5 Video player as well (possibility of using existing flash FlowPlayer for flv files will remain).&lt;br /&gt;
&lt;br /&gt;
== Mock-Ups/Prototypes ==&lt;br /&gt;
&lt;br /&gt;
See [[#Sample_Pages|Sample pages]] section.&lt;br /&gt;
&lt;br /&gt;
== Workaround ==&lt;br /&gt;
&lt;br /&gt;
As intermediate solution, if you require player consistency throughout all browsers and platforms, you may consider using JW Player filter: https://github.com/lucisgit/moodle-filter_jwplayer Notice, that JW Player is not free for commercial use.&lt;br /&gt;
&lt;br /&gt;
== Related Tracker Issues ==&lt;br /&gt;
* MDL-38158&lt;br /&gt;
&lt;br /&gt;
== Useful links ==&lt;br /&gt;
* http://praegnanz.de/html5video/&lt;br /&gt;
* http://html5video.org/wiki/HTML5_Video_Player_Comparison&lt;br /&gt;
* http://www.streamingmedia.com/Articles/Editorial/Featured-Articles/Choosing-a-Video-Player-Features-and-Specs-for-the-Top-Five-94188.aspx&lt;br /&gt;
&lt;br /&gt;
[[Category:Project]]&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=44490</id>
		<title>HTML5 player</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=44490"/>
		<updated>2014-04-17T22:20:57Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}&lt;br /&gt;
{{Infobox Project&lt;br /&gt;
|name = HTML5 Player with flash fallback&lt;br /&gt;
|state = In Development&lt;br /&gt;
|tracker = https://tracker.moodle.org/browse/MDL-38158&lt;br /&gt;
|discussion = https://moodle.org/mod/forum/discuss.php?d=222753#p1110024&lt;br /&gt;
|assignee = [https://tracker.moodle.org/secure/ViewProfile.jspa?name=kabalin Ruslan Kabalin]&lt;br /&gt;
}}&lt;br /&gt;
{{Moodle 2.x}}&lt;br /&gt;
&lt;br /&gt;
== Project goals ==&lt;br /&gt;
&lt;br /&gt;
The purpose of this document is to choose HTML5 player with flash fallback for integration in Moodle and plan its implementation.&lt;br /&gt;
&lt;br /&gt;
The aim of this change is to reach a consistent look of the player among different platforms and browsers, as well as making sure that player starts using flash if html5 is not supported by browser for the given format. Another aim is to improve accessibility and usability, enhance customisation.&lt;br /&gt;
&lt;br /&gt;
== Considerations ==&lt;br /&gt;
&lt;br /&gt;
* Usability of the player - is it easy to use it and intuitively understand how to use controls?&lt;br /&gt;
* Accessibility of the player - possibility of keyboard navigation, subtitles, support?&lt;br /&gt;
* Appearance of the player - can its interface be modified, themes support, RTL?&lt;br /&gt;
* Consistency among browsers - does player look the same?&lt;br /&gt;
* Audio support - can player handle HTML5 &amp;lt;audio&amp;gt; tag?&lt;br /&gt;
* Mobile platforms support - does player also work on iOS and Android?&lt;br /&gt;
* Streaming media support (including adaptive-bitrate delivery) - can player handle RTMP, Apple HLS, Adobe HDS, Microsoft HSS?&lt;br /&gt;
* Plugins support - can we use or develop community plugins easily?&lt;br /&gt;
* Embedding support - so users could post media content outside Moodle, if permitted.&lt;br /&gt;
* Maintainability of the links between the player and Moodle - how much work will we need to do every time we upgrade?&lt;br /&gt;
&lt;br /&gt;
== Candidates ==&lt;br /&gt;
&lt;br /&gt;
* [http://flowplayer.org/ Flowplayer HTML5]&lt;br /&gt;
* [http://www.videojs.com/ Video.JS]&lt;br /&gt;
* [http://www.projekktor.com/ Projekktor]&lt;br /&gt;
* ?Are there other alternatives?&lt;br /&gt;
&lt;br /&gt;
== Comparison Matrix ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! [[#Flowplayer_HTML5|Flowplayer HTML5]]&lt;br /&gt;
! [[#Video.JS|Video.JS]]&lt;br /&gt;
! [[#Projekktor|Projekktor]]&lt;br /&gt;
! No Player&lt;br /&gt;
|-&lt;br /&gt;
! Accessible Player:&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Keyboard control&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes (configurable)&lt;br /&gt;
| unknown&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Subtitles support&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via plugin)&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Touch interface&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Appearance:&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Skins&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* CSS customisation&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| unknown&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTL support&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| No&lt;br /&gt;
| Unknown&lt;br /&gt;
|-&lt;br /&gt;
! Mobile platforms:&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* iOS&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Android&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Streaming protocols:&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTMP&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via playlist)&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Adaptive HTTP&lt;br /&gt;
| HLS&lt;br /&gt;
| HLS (via plugin)&lt;br /&gt;
| HLS (via playlist)&lt;br /&gt;
| Only in Chrome so far (Media Source Extension)&lt;br /&gt;
|-&lt;br /&gt;
! Audio player&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Embedding support&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (configurable)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via addThis plugin)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via plugin)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | No&lt;br /&gt;
|-&lt;br /&gt;
! License&lt;br /&gt;
| GPL v3 (with additional terms)&lt;br /&gt;
| Apache 2&lt;br /&gt;
| GPL v3&lt;br /&gt;
| no extra code needed&lt;br /&gt;
|-&lt;br /&gt;
! JS library&lt;br /&gt;
| jQuery&lt;br /&gt;
| -&lt;br /&gt;
| jQuery&lt;br /&gt;
| none required&lt;br /&gt;
|-&lt;br /&gt;
! Plugins infrastructure&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
! Flash fallback player&lt;br /&gt;
| Flowplayer Flash&lt;br /&gt;
| video-js flash&lt;br /&gt;
| StobeMediaPlayback (but can be jarisplayer or some other).&lt;br /&gt;
| VideoForEverybody can allow you to use any Flash player as fallback.&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
! API&lt;br /&gt;
| Yes (plus window.flowplayer object)&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Flowplayer HTML5 ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* Good looking player, resembles existing flash flowplayer in Moodle (with &amp;quot;functional&amp;quot; skin)&lt;br /&gt;
* Extensive customisation (via CSS3 skins and configuration object)&lt;br /&gt;
* Streaming support (RTMP, HLS)&lt;br /&gt;
* Good accessibility features&lt;br /&gt;
* Configurable embedding functionality&lt;br /&gt;
* Existing flash flowplayer can be configured for fallback (the appearance of player will not be affected).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Require jQuery for functioning&lt;br /&gt;
* Flowplayer logo remains on screen&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using wrapper around &amp;lt;video&amp;gt;.&lt;br /&gt;
* width and height attributes in video tag are ignored, player size is configured via wrapper size only.&lt;br /&gt;
* RTMP server connection is configured via data-rtmp attribute in wrapper or player init config parameter, actual path the file specified in src attribute of source item.&lt;br /&gt;
* &amp;lt;source type=&amp;quot;video/flash&amp;quot;... dummy MIME type to force using plash player for whatever content.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Plugins infrastructure&lt;br /&gt;
* No audio support&lt;br /&gt;
&lt;br /&gt;
=== Video.JS ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Extensive API.&lt;br /&gt;
* No extra JS library needed.&lt;br /&gt;
* Many plugins.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Poor documentation&lt;br /&gt;
* RTMP requires non-standard MIME.&lt;br /&gt;
* Android and iOS override Video.JS with own player, when not overridden, content is not playing.&lt;br /&gt;
* No RTL.&lt;br /&gt;
* HLS support via plugin (many files to include, external contributor see https://github.com/videojs/videojs-contrib-hls).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* RTMP server connection and path specified as single URI in src attribute of source item, &#039;&amp;amp;&#039; character is used as server connection and path divider.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Embedded HLS support.&lt;br /&gt;
&lt;br /&gt;
=== Projekktor ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Well documented API.&lt;br /&gt;
* Media RSS support.&lt;br /&gt;
* Possibility to choose flash player for fallback (included by default are StrobeMediaPlayback and Jarisplayer, both Open Source).&lt;br /&gt;
* Platform preference order selection (e.g. browser, ios, android, flash, native).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Uses flash where it is not supposed to (e.g. mp4 in Chrome).&lt;br /&gt;
* Issues on ios and android (suggests to download file when play button is pressed).&lt;br /&gt;
* RTMP only work if defined via playlist rather than in &amp;lt;source&amp;gt; tags.&lt;br /&gt;
* Subtitles plugin is not free.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* Make sure &amp;lt;video&amp;gt; tag has class attribute with &#039;projekktor&#039; value (even if you initialise it by ID of the element), player will not work properly otherwise.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== HTML5 browser native ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* Simple&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* IE8 has no support&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes&#039;&#039;&#039;&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Cross-browser support ==&lt;br /&gt;
&lt;br /&gt;
=== Method ===&lt;br /&gt;
Compatibility checks were done manually by accessing the sample page using different browsers and platforms. Sample page contained the list of identical player instances, initialised for each &amp;lt;video&amp;gt; definition with a &amp;lt;source&amp;gt; of particular format: mp4, webm, ogg, flv. Streaming support was checked by setting up a &amp;lt;video&amp;gt; container with two sources of the same video, one was HLS (Apple HTTP Live Streaming) stream for browsers and platforms that support html5 video streaming, another one was RTMP which is played using flash engine and supposed to be used in case if HLS is not supported.&lt;br /&gt;
&lt;br /&gt;
=== Sample Pages ===&lt;br /&gt;
&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=flowplayer Flowplayer HTML5] version 5.4.6.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=videojs Video.JS] version 4.4.1.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=projekktor Projekktor] version 1.3.09.&lt;br /&gt;
&lt;br /&gt;
=== Source ===&lt;br /&gt;
&lt;br /&gt;
Source of testing page is hosted on [https://github.com/kabalin/test-html5-players/blob/master/players.php github]. The actual source of the html page can be viewed in browser.&lt;br /&gt;
&lt;br /&gt;
=== Discussion ===&lt;br /&gt;
&lt;br /&gt;
The players comparison that has been carried out demonstrated that &amp;quot;least hassle&amp;quot; player is Flowplayer. Despite some drawbacks listed in [[#Flowplayer_HTML5|corresponding section above]], it is clearly a winner as it works as expected and according to documentation for all browsers and platforms I had chance to test it. This is the only player that supports RTL layout, display platform incompatibility message prior to attempt to play, and was simple to configure (no undocumented tricks that I had to figure out to make it work). Both VideoJS and Projekktor do now perform properly in all cases. Among those two, I personally prefer Projekktor more for its extensive API, plugins infrastructure and configuration flexibility. However problems on mobile platforms and flash fallback inconsistency make them unreliable at this stage.&lt;br /&gt;
&lt;br /&gt;
=== Compatibility results ===&lt;br /&gt;
&lt;br /&gt;
The table was populated using Flowplayer as others do not perform good enough with some formats and platforms, e.g. VideoJS allow mobile platform player to override itself, Projekktor does not always use HTML5 where browser clearly can handle it (supported in native mode and Flowplayer).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Browser&lt;br /&gt;
! mp4&lt;br /&gt;
! webm&lt;br /&gt;
! ogg&lt;br /&gt;
! flv&lt;br /&gt;
! RTMP/HLS*&lt;br /&gt;
|-&lt;br /&gt;
! Windows 7&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Firefox 27.0.1&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 12.16&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 5.1.7&lt;br /&gt;
| flash&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Internet Explorer 11.0.9600.x&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Linux (Debian Wheezy)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.115&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! OSX 10.9&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 7.0 (9537.71)&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 phone (CyanogenMod, no flash)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 tablet (GalaxyTab2, flash app 11.1.115.36)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 19.0.1340.x&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
! iPhone 4S (6.1.3)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! iPad 4 (7.0.6)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;small&amp;gt;* For HLS/RTMP, html5 in the table means HLS has been used, flash means player fell back and used RTMP.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sub Tasks ==&lt;br /&gt;
&lt;br /&gt;
In initial stage FlowPlayer HTML5 (or any other) will handle all existing HTML5 Video extensions as per core_media_player_html5video class, plus m3u8 (HLS). It will also be possible optionally to make flash files handled by HTML5 Video player as well (possibility of using existing flash FlowPlayer for flv files will remain).&lt;br /&gt;
&lt;br /&gt;
== Mock-Ups/Prototypes ==&lt;br /&gt;
&lt;br /&gt;
See [[#Sample_Pages|Sample pages]] section.&lt;br /&gt;
&lt;br /&gt;
== Workaround ==&lt;br /&gt;
&lt;br /&gt;
As intermediate solution, if you require player consistency throughout all browsers and platforms, you may consider using JW Player filter: https://github.com/lucisgit/moodle-filter_jwplayer Notice, that JW Player is not free for commercial use.&lt;br /&gt;
&lt;br /&gt;
== Related Tracker Issues ==&lt;br /&gt;
* MDL-38158&lt;br /&gt;
&lt;br /&gt;
== Useful links ==&lt;br /&gt;
* http://praegnanz.de/html5video/&lt;br /&gt;
* http://html5video.org/wiki/HTML5_Video_Player_Comparison&lt;br /&gt;
* http://www.streamingmedia.com/Articles/Editorial/Featured-Articles/Choosing-a-Video-Player-Features-and-Specs-for-the-Top-Five-94188.aspx&lt;br /&gt;
&lt;br /&gt;
[[Category:Project]]&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=44489</id>
		<title>HTML5 player</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=44489"/>
		<updated>2014-04-17T22:20:15Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}&lt;br /&gt;
{{Infobox Project&lt;br /&gt;
|name = HTML5 Player with flash fallback&lt;br /&gt;
|state = In Development&lt;br /&gt;
|tracker = https://tracker.moodle.org/browse/MDL-38158&lt;br /&gt;
|discussion = https://moodle.org/mod/forum/discuss.php?d=222753#p1110024&lt;br /&gt;
|assignee = [https://tracker.moodle.org/secure/ViewProfile.jspa?name=kabalin Ruslan Kabalin]&lt;br /&gt;
}}&lt;br /&gt;
{{Moodle 2.x}}&lt;br /&gt;
&lt;br /&gt;
== Project goals ==&lt;br /&gt;
&lt;br /&gt;
The purpose of this document is to choose HTML5 player with flash fallback for integration in Moodle and plan its implementation.&lt;br /&gt;
&lt;br /&gt;
The aim of this change is to reach a consistent look of the player among different platforms and browsers, as well as making sure that player starts using flash if html5 is not supported by browser for the given format. Another aim is to improve accessibility and usability, enhance customisation.&lt;br /&gt;
&lt;br /&gt;
== Considerations ==&lt;br /&gt;
&lt;br /&gt;
* Usability of the player - is it easy to use it and intuitively understand how to use controls?&lt;br /&gt;
* Accessibility of the player - possibility of keyboard navigation, subtitles, support?&lt;br /&gt;
* Appearance of the player - can its interface be modified, themes support, RTL?&lt;br /&gt;
* Consistency among browsers - does player look the same?&lt;br /&gt;
* Audio support - can player handle HTML5 &amp;lt;audio&amp;gt; tag?&lt;br /&gt;
* Mobile platforms support - does player also work on iOS and Android?&lt;br /&gt;
* Streaming media support (including adaptive-bitrate delivery) - can player handle RTMP, Apple HLS, Adobe HDS, Microsoft HSS?&lt;br /&gt;
* Plugins support - can we use or develop community plugins easily?&lt;br /&gt;
* Embedding support - so users could post media content outside Moodle, if permitted.&lt;br /&gt;
* Maintainability of the links between the player and Moodle - how much work will we need to do every time we upgrade?&lt;br /&gt;
&lt;br /&gt;
== Candidates ==&lt;br /&gt;
&lt;br /&gt;
* [http://flowplayer.org/ Flowplayer HTML5]&lt;br /&gt;
* [http://www.videojs.com/ Video.JS]&lt;br /&gt;
* [http://www.projekktor.com/ Projekktor]&lt;br /&gt;
* ?Are there other alternatives?&lt;br /&gt;
&lt;br /&gt;
== Comparison Matrix ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! [[#Flowplayer_HTML5|Flowplayer HTML5]]&lt;br /&gt;
! [[#Video.JS|Video.JS]]&lt;br /&gt;
! [[#Projekktor|Projekktor]]&lt;br /&gt;
! No Player&lt;br /&gt;
|-&lt;br /&gt;
! Accessible Player:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Keyboard control&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes (configurable)&lt;br /&gt;
| unknown&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Subtitles support&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via plugin)&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Touch interface&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Appearance:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Skins&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* CSS customisation&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| unknown&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTL support&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| No&lt;br /&gt;
| Unknown&lt;br /&gt;
|-&lt;br /&gt;
! Mobile platforms:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* iOS&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Android&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Streaming protocols:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTMP&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via playlist)&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Adaptive HTTP&lt;br /&gt;
| HLS&lt;br /&gt;
| HLS (via plugin)&lt;br /&gt;
| HLS (via playlist)&lt;br /&gt;
| Only in Chrome so far (Media Source Extension)&lt;br /&gt;
|-&lt;br /&gt;
! Audio player&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Embedding support&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (configurable)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via addThis plugin)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via plugin)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | No&lt;br /&gt;
|-&lt;br /&gt;
! License&lt;br /&gt;
| GPL v3 (with additional terms)&lt;br /&gt;
| Apache 2&lt;br /&gt;
| GPL v3&lt;br /&gt;
| no extra code needed&lt;br /&gt;
|-&lt;br /&gt;
! JS library&lt;br /&gt;
| jQuery&lt;br /&gt;
| -&lt;br /&gt;
| jQuery&lt;br /&gt;
| none required&lt;br /&gt;
|-&lt;br /&gt;
! Plugins infrastructure&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
! Flash fallback player&lt;br /&gt;
| Flowplayer Flash&lt;br /&gt;
| video-js flash&lt;br /&gt;
| StobeMediaPlayback (but can be jarisplayer or some other).&lt;br /&gt;
| VideoForEverybody can allow you to use any Flash player as fallback.&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
! API&lt;br /&gt;
| Yes (plus window.flowplayer object)&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Flowplayer HTML5 ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* Good looking player, resembles existing flash flowplayer in Moodle (with &amp;quot;functional&amp;quot; skin)&lt;br /&gt;
* Extensive customisation (via CSS3 skins and configuration object)&lt;br /&gt;
* Streaming support (RTMP, HLS)&lt;br /&gt;
* Good accessibility features&lt;br /&gt;
* Configurable embedding functionality&lt;br /&gt;
* Existing flash flowplayer can be configured for fallback (the appearance of player will not be affected).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Require jQuery for functioning&lt;br /&gt;
* Flowplayer logo remains on screen&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using wrapper around &amp;lt;video&amp;gt;.&lt;br /&gt;
* width and height attributes in video tag are ignored, player size is configured via wrapper size only.&lt;br /&gt;
* RTMP server connection is configured via data-rtmp attribute in wrapper or player init config parameter, actual path the file specified in src attribute of source item.&lt;br /&gt;
* &amp;lt;source type=&amp;quot;video/flash&amp;quot;... dummy MIME type to force using plash player for whatever content.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Plugins infrastructure&lt;br /&gt;
* No audio support&lt;br /&gt;
&lt;br /&gt;
=== Video.JS ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Extensive API.&lt;br /&gt;
* No extra JS library needed.&lt;br /&gt;
* Many plugins.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Poor documentation&lt;br /&gt;
* RTMP requires non-standard MIME.&lt;br /&gt;
* Android and iOS override Video.JS with own player, when not overridden, content is not playing.&lt;br /&gt;
* No RTL.&lt;br /&gt;
* HLS support via plugin (many files to include, external contributor see https://github.com/videojs/videojs-contrib-hls).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* RTMP server connection and path specified as single URI in src attribute of source item, &#039;&amp;amp;&#039; character is used as server connection and path divider.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Embedded HLS support.&lt;br /&gt;
&lt;br /&gt;
=== Projekktor ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Well documented API.&lt;br /&gt;
* Media RSS support.&lt;br /&gt;
* Possibility to choose flash player for fallback (included by default are StrobeMediaPlayback and Jarisplayer, both Open Source).&lt;br /&gt;
* Platform preference order selection (e.g. browser, ios, android, flash, native).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Uses flash where it is not supposed to (e.g. mp4 in Chrome).&lt;br /&gt;
* Issues on ios and android (suggests to download file when play button is pressed).&lt;br /&gt;
* RTMP only work if defined via playlist rather than in &amp;lt;source&amp;gt; tags.&lt;br /&gt;
* Subtitles plugin is not free.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* Make sure &amp;lt;video&amp;gt; tag has class attribute with &#039;projekktor&#039; value (even if you initialise it by ID of the element), player will not work properly otherwise.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== HTML5 browser native ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* Simple&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* IE8 has no support&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes&#039;&#039;&#039;&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Cross-browser support ==&lt;br /&gt;
&lt;br /&gt;
=== Method ===&lt;br /&gt;
Compatibility checks were done manually by accessing the sample page using different browsers and platforms. Sample page contained the list of identical player instances, initialised for each &amp;lt;video&amp;gt; definition with a &amp;lt;source&amp;gt; of particular format: mp4, webm, ogg, flv. Streaming support was checked by setting up a &amp;lt;video&amp;gt; container with two sources of the same video, one was HLS (Apple HTTP Live Streaming) stream for browsers and platforms that support html5 video streaming, another one was RTMP which is played using flash engine and supposed to be used in case if HLS is not supported.&lt;br /&gt;
&lt;br /&gt;
=== Sample Pages ===&lt;br /&gt;
&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=flowplayer Flowplayer HTML5] version 5.4.6.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=videojs Video.JS] version 4.4.1.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=projekktor Projekktor] version 1.3.09.&lt;br /&gt;
&lt;br /&gt;
=== Source ===&lt;br /&gt;
&lt;br /&gt;
Source of testing page is hosted on [https://github.com/kabalin/test-html5-players/blob/master/players.php github]. The actual source of the html page can be viewed in browser.&lt;br /&gt;
&lt;br /&gt;
=== Discussion ===&lt;br /&gt;
&lt;br /&gt;
The players comparison that has been carried out demonstrated that &amp;quot;least hassle&amp;quot; player is Flowplayer. Despite some drawbacks listed in [[#Flowplayer_HTML5|corresponding section above]], it is clearly a winner as it works as expected and according to documentation for all browsers and platforms I had chance to test it. This is the only player that supports RTL layout, display platform incompatibility message prior to attempt to play, and was simple to configure (no undocumented tricks that I had to figure out to make it work). Both VideoJS and Projekktor do now perform properly in all cases. Among those two, I personally prefer Projekktor more for its extensive API, plugins infrastructure and configuration flexibility. However problems on mobile platforms and flash fallback inconsistency make them unreliable at this stage.&lt;br /&gt;
&lt;br /&gt;
=== Compatibility results ===&lt;br /&gt;
&lt;br /&gt;
The table was populated using Flowplayer as others do not perform good enough with some formats and platforms, e.g. VideoJS allow mobile platform player to override itself, Projekktor does not always use HTML5 where browser clearly can handle it (supported in native mode and Flowplayer).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Browser&lt;br /&gt;
! mp4&lt;br /&gt;
! webm&lt;br /&gt;
! ogg&lt;br /&gt;
! flv&lt;br /&gt;
! RTMP/HLS*&lt;br /&gt;
|-&lt;br /&gt;
! Windows 7&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Firefox 27.0.1&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 12.16&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 5.1.7&lt;br /&gt;
| flash&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Internet Explorer 11.0.9600.x&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Linux (Debian Wheezy)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.115&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! OSX 10.9&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 7.0 (9537.71)&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 phone (CyanogenMod, no flash)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 tablet (GalaxyTab2, flash app 11.1.115.36)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 19.0.1340.x&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
! iPhone 4S (6.1.3)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! iPad 4 (7.0.6)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;small&amp;gt;* For HLS/RTMP, html5 in the table means HLS has been used, flash means player fell back and used RTMP.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sub Tasks ==&lt;br /&gt;
&lt;br /&gt;
In initial stage FlowPlayer HTML5 (or any other) will handle all existing HTML5 Video extensions as per core_media_player_html5video class, plus m3u8 (HLS). It will also be possible optionally to make flash files handled by HTML5 Video player as well (possibility of using existing flash FlowPlayer for flv files will remain).&lt;br /&gt;
&lt;br /&gt;
== Mock-Ups/Prototypes ==&lt;br /&gt;
&lt;br /&gt;
See [[#Sample_Pages|Sample pages]] section.&lt;br /&gt;
&lt;br /&gt;
== Workaround ==&lt;br /&gt;
&lt;br /&gt;
As intermediate solution, if you require player consistency throughout all browsers and platforms, you may consider using JW Player filter: https://github.com/lucisgit/moodle-filter_jwplayer Notice, that JW Player is not free for commercial use.&lt;br /&gt;
&lt;br /&gt;
== Related Tracker Issues ==&lt;br /&gt;
* MDL-38158&lt;br /&gt;
&lt;br /&gt;
== Useful links ==&lt;br /&gt;
* http://praegnanz.de/html5video/&lt;br /&gt;
* http://html5video.org/wiki/HTML5_Video_Player_Comparison&lt;br /&gt;
* http://www.streamingmedia.com/Articles/Editorial/Featured-Articles/Choosing-a-Video-Player-Features-and-Specs-for-the-Top-Five-94188.aspx&lt;br /&gt;
&lt;br /&gt;
[[Category:Project]]&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=44479</id>
		<title>HTML5 player</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=44479"/>
		<updated>2014-04-17T13:51:27Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}&lt;br /&gt;
{{Infobox Project&lt;br /&gt;
|name = HTML5 Player with flash fallback&lt;br /&gt;
|state = In Development&lt;br /&gt;
|tracker = https://tracker.moodle.org/browse/MDL-38158&lt;br /&gt;
|discussion = https://moodle.org/mod/forum/discuss.php?d=222753#p1110024&lt;br /&gt;
|assignee = [https://tracker.moodle.org/secure/ViewProfile.jspa?name=kabalin Ruslan Kabalin]&lt;br /&gt;
}}&lt;br /&gt;
{{Moodle 2.x}}&lt;br /&gt;
&lt;br /&gt;
== Project goals ==&lt;br /&gt;
&lt;br /&gt;
The purpose of this document is to choose HTML5 player with flash fallback for integration in Moodle and plan its implementation.&lt;br /&gt;
&lt;br /&gt;
The aim of this change is to reach a consistent look of the player among different platforms and browsers, as well as making sure that player starts using flash if html5 is not supported by browser for the given format. Another aim is to improve accessibility and usability, enhance customisation.&lt;br /&gt;
&lt;br /&gt;
== Considerations ==&lt;br /&gt;
&lt;br /&gt;
* Usability of the player - is it easy to use it and intuitively understand how to use controls?&lt;br /&gt;
* Accessibility of the player - possibility of keyboard navigation, subtitles, support?&lt;br /&gt;
* Appearance of the player - can its interface be modified, themes support, RTL?&lt;br /&gt;
* Consistency among browsers - does player look the same?&lt;br /&gt;
* Audio support - can player handle HTML5 &amp;lt;audio&amp;gt; tag?&lt;br /&gt;
* Mobile platforms support - does player also work on iOS and Android?&lt;br /&gt;
* Streaming media support (including adaptive-bitrate delivery) - can player handle RTMP, Apple HLS, Adobe HDS, Microsoft HSS?&lt;br /&gt;
* Plugins support - can we use or develop community plugins easily?&lt;br /&gt;
* Embedding support - so users could post media content outside Moodle, if permitted.&lt;br /&gt;
* Maintainability of the links between the player and Moodle - how much work will we need to do every time we upgrade?&lt;br /&gt;
&lt;br /&gt;
== Candidates ==&lt;br /&gt;
&lt;br /&gt;
* [http://flowplayer.org/ Flowplayer HTML5]&lt;br /&gt;
* [http://www.videojs.com/ Video.JS]&lt;br /&gt;
* [http://www.projekktor.com/ Projekktor]&lt;br /&gt;
* ?Are there other alternatives?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! [[#Flowplayer_HTML5|Flowplayer HTML5]]&lt;br /&gt;
! [[#Video.JS|Video.JS]]&lt;br /&gt;
! [[#Projekktor|Projekktor]]&lt;br /&gt;
! No Player&lt;br /&gt;
|-&lt;br /&gt;
! Accessible Player:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Keyboard control&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes (configurable)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Subtitles support&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via plugin)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Touch interface&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Appearance:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Skins&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* CSS customisation&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTL support&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
! Mobile platforms:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* iOS&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Android&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Streaming protocols:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTMP&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via playlist)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Adaptive HTTP&lt;br /&gt;
| HLS&lt;br /&gt;
| HLS (via plugin)&lt;br /&gt;
| HLS (via playlist)&lt;br /&gt;
|-&lt;br /&gt;
! Audio player&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Embedding support&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (configurable)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via addThis plugin)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via plugin)&lt;br /&gt;
|-&lt;br /&gt;
! License&lt;br /&gt;
| GPL v3 (with additional terms)&lt;br /&gt;
| Apache 2&lt;br /&gt;
| GPL v3&lt;br /&gt;
|-&lt;br /&gt;
! JS library&lt;br /&gt;
| jQuery&lt;br /&gt;
| -&lt;br /&gt;
| jQuery&lt;br /&gt;
|-&lt;br /&gt;
! Plugins infrastructure&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Flash fallback player&lt;br /&gt;
| Flowplayer Flash&lt;br /&gt;
| video-js flash&lt;br /&gt;
| StobeMediaPlayback (but can be jarisplayer or some other).&lt;br /&gt;
|-&lt;br /&gt;
! API&lt;br /&gt;
| Yes (plus window.flowplayer object)&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Flowplayer HTML5 ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* Good looking player, resembles existing flash flowplayer in Moodle (with &amp;quot;functional&amp;quot; skin)&lt;br /&gt;
* Extensive customisation (via CSS3 skins and configuration object)&lt;br /&gt;
* Streaming support (RTMP, HLS)&lt;br /&gt;
* Good accessibility features&lt;br /&gt;
* Configurable embedding functionality&lt;br /&gt;
* Existing flash flowplayer can be configured for fallback (the appearance of player will not be affected).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Require jQuery for functioning&lt;br /&gt;
* Flowplayer logo remains on screen&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using wrapper around &amp;lt;video&amp;gt;.&lt;br /&gt;
* width and height attributes in video tag are ignored, player size is configured via wrapper size only.&lt;br /&gt;
* RTMP server connection is configured via data-rtmp attribute in wrapper or player init config parameter, actual path the file specified in src attribute of source item.&lt;br /&gt;
* &amp;lt;source type=&amp;quot;video/flash&amp;quot;... dummy MIME type to force using plash player for whatever content.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Plugins infrastructure&lt;br /&gt;
* No audio support&lt;br /&gt;
&lt;br /&gt;
=== Video.JS ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Extensive API.&lt;br /&gt;
* No extra JS library needed.&lt;br /&gt;
* Many plugins.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Poor documentation&lt;br /&gt;
* RTMP requires non-standard MIME.&lt;br /&gt;
* Android and iOS override Video.JS with own player, when not overridden, content is not playing.&lt;br /&gt;
* No RTL.&lt;br /&gt;
* HLS support via plugin (many files to include, external contributor see https://github.com/videojs/videojs-contrib-hls).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* RTMP server connection and path specified as single URI in src attribute of source item, &#039;&amp;amp;&#039; character is used as server connection and path divider.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Embedded HLS support.&lt;br /&gt;
&lt;br /&gt;
=== Projekktor ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Well documented API.&lt;br /&gt;
* Media RSS support.&lt;br /&gt;
* Possibility to choose flash player for fallback (included by default are StrobeMediaPlayback and Jarisplayer, both Open Source).&lt;br /&gt;
* Platform preference order selection (e.g. browser, ios, android, flash, native).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Uses flash where it is not supposed to (e.g. mp4 in Chrome).&lt;br /&gt;
* Issues on ios and android (suggests to download file when play button is pressed).&lt;br /&gt;
* RTMP only work if defined via playlist rather than in &amp;lt;source&amp;gt; tags.&lt;br /&gt;
* Subtitles plugin is not free.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* Make sure &amp;lt;video&amp;gt; tag has class attribute with &#039;projekktor&#039; value (even if you initialise it by ID of the element), player will not work properly otherwise.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Cross-browser support ==&lt;br /&gt;
&lt;br /&gt;
=== Method ===&lt;br /&gt;
Compatibility checks were done manually by accessing the sample page using different browsers and platforms. Sample page contained the list of identical player instances, initialised for each &amp;lt;video&amp;gt; definition with a &amp;lt;source&amp;gt; of particular format: mp4, webm, ogg, flv. Streaming support was checked by setting up a &amp;lt;video&amp;gt; container with two sources of the same video, one was HLS (Apple HTTP Live Streaming) stream for browsers and platforms that support html5 video streaming, another one was RTMP which is played using flash engine and supposed to be used in case if HLS is not supported.&lt;br /&gt;
&lt;br /&gt;
=== Sample Pages ===&lt;br /&gt;
&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=flowplayer Flowplayer HTML5] version 5.4.6.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=videojs Video.JS] version 4.4.1.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=projekktor Projekktor] version 1.3.09.&lt;br /&gt;
&lt;br /&gt;
=== Source ===&lt;br /&gt;
&lt;br /&gt;
Source of testing page is hosted on [https://github.com/kabalin/test-html5-players/blob/master/players.php github]. The actual source of the html page can be viewed in browser.&lt;br /&gt;
&lt;br /&gt;
=== Discussion ===&lt;br /&gt;
&lt;br /&gt;
The players comparison that has been carried out demonstrated that &amp;quot;least hassle&amp;quot; player is Flowplayer. Despite some drawbacks listed in [[#Flowplayer_HTML5|corresponding section above]], it is clearly a winner as it works as expected and according to documentation for all browsers and platforms I had chance to test it. This is the only player that supports RTL layout, display platform incompatibility message prior to attempt to play, and was simple to configure (no undocumented tricks that I had to figure out to make it work). Both VideoJS and Projekktor do now perform properly in all cases. Among those two, I personally prefer Projekktor more for its extensive API, plugins infrastructure and configuration flexibility. However problems on mobile platforms and flash fallback inconsistency make them unreliable at this stage.&lt;br /&gt;
&lt;br /&gt;
=== Compatibility results ===&lt;br /&gt;
&lt;br /&gt;
The table was populated using Flowplayer as others do not perform good enough with some formats and platforms, e.g. VideoJS allow mobile platform player to override itself, Projekktor does not always use HTML5 where browser clearly can handle it (supported in native mode and Flowplayer).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Browser&lt;br /&gt;
! mp4&lt;br /&gt;
! webm&lt;br /&gt;
! ogg&lt;br /&gt;
! flv&lt;br /&gt;
! RTMP/HLS*&lt;br /&gt;
|-&lt;br /&gt;
! Windows 7&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Firefox 27.0.1&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 12.16&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 5.1.7&lt;br /&gt;
| flash&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Internet Explorer 11.0.9600.x&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Linux (Debian Wheezy)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.115&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! OSX 10.9&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 7.0 (9537.71)&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 phone (CyanogenMod, no flash)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 tablet (GalaxyTab2, flash app 11.1.115.36)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 19.0.1340.x&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
! iPhone 4S (6.1.3)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! iPad 4 (7.0.6)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;small&amp;gt;* For HLS/RTMP, html5 in the table means HLS has been used, flash means player fell back and used RTMP.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sub Tasks ==&lt;br /&gt;
&lt;br /&gt;
In initial stage FlowPlayer HTML5 (or any other) will handle all existing HTML5 Video extensions as per core_media_player_html5video class, plus m3u8 (HLS). It will also be possible optionally to make flash files handled by HTML5 Video player as well (possibility of using existing flash FlowPlayer for flv files will remain).&lt;br /&gt;
&lt;br /&gt;
== Mock-Ups/Prototypes ==&lt;br /&gt;
&lt;br /&gt;
See [[#Sample_Pages|Sample pages]] section.&lt;br /&gt;
&lt;br /&gt;
== Workaround ==&lt;br /&gt;
&lt;br /&gt;
As intermediate solution, if you require player consistency throughout all browsers and platforms, you may consider using JW Player filter: https://github.com/lucisgit/moodle-filter_jwplayer Notice, that JW Player is not free for commercial use.&lt;br /&gt;
&lt;br /&gt;
== Related Tracker Issues ==&lt;br /&gt;
* MDL-38158&lt;br /&gt;
&lt;br /&gt;
== Useful links ==&lt;br /&gt;
* http://praegnanz.de/html5video/&lt;br /&gt;
* http://html5video.org/wiki/HTML5_Video_Player_Comparison&lt;br /&gt;
* http://www.streamingmedia.com/Articles/Editorial/Featured-Articles/Choosing-a-Video-Player-Features-and-Specs-for-the-Top-Five-94188.aspx&lt;br /&gt;
&lt;br /&gt;
[[Category:Project]]&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Hackfest_UK_2014&amp;diff=44474</id>
		<title>Hackfest UK 2014</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Hackfest_UK_2014&amp;diff=44474"/>
		<updated>2014-04-17T13:12:35Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: /* Session 3 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[file:Hackfest_Logo_-_Narrow.png|202|right]]&lt;br /&gt;
&lt;br /&gt;
[[Developer meetings]] &amp;gt; UK Hackfest April 2014&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| When&lt;br /&gt;
| Thu 14 April, 2014&lt;br /&gt;
|-&lt;br /&gt;
| Where&lt;br /&gt;
| Moodlemoot Edinburgh, UK&lt;br /&gt;
|-&lt;br /&gt;
| Alternate name&lt;br /&gt;
| Haven&#039;t come up with one yet&lt;br /&gt;
|-&lt;br /&gt;
| Hashtag&lt;br /&gt;
| [https://twitter.com/search/%23mootuk14 #mootuk14]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== What happened? ==&lt;br /&gt;
&lt;br /&gt;
A Hackfest brings together Moodle developers to brainstorm future Moodle developments.&lt;br /&gt;
&lt;br /&gt;
A description of the activities at the Hackfest will be added here.&lt;br /&gt;
&lt;br /&gt;
== Group notes ==&lt;br /&gt;
&lt;br /&gt;
===Tools===&lt;br /&gt;
&lt;br /&gt;
* Php Xref&lt;br /&gt;
* Xdebug + IDE&lt;br /&gt;
* XHprof&lt;br /&gt;
* codechecker&lt;br /&gt;
* PHPUnit&lt;br /&gt;
* MDK&lt;br /&gt;
* Moosh&lt;br /&gt;
* Grunt&lt;br /&gt;
* Git&lt;br /&gt;
&lt;br /&gt;
==Specifications==&lt;br /&gt;
&lt;br /&gt;
Specifications from subsequent work will be liked from here&lt;br /&gt;
&lt;br /&gt;
=== Session 1 ===&lt;br /&gt;
&lt;br /&gt;
* [https://docs.google.com/document/d/1iisKZks8e_JqjpGTXip1dJ9hS29QsGG4mSomKcFGVRg/edit?usp=sharing Moodle element library notes]&lt;br /&gt;
*[https://docs.google.com/document/d/1mlJjxewBOaZyQ14C0KIe5aV38hCmWF5aIQldlw-EwmU/edit?usp=sharing Moodle Analytics Notes]&lt;br /&gt;
* [[Hackfest_UK_2014/LTI|LTI Usability Improvements notes]]&lt;br /&gt;
&lt;br /&gt;
=== Session 2 ===&lt;br /&gt;
&lt;br /&gt;
* [https://docs.google.com/document/d/1XjiVY3ax9EuZ7gneofJR9z330rdI9bhD0yoOzt5tYRY/edit?usp=sharing Lesson refactoring notes]&lt;br /&gt;
* [[Hackfest_UK_2014/Email Logging|Email Logging Functionality and Reporting notes]]&lt;br /&gt;
* [[Hackfest_UK_2014/Bootstrap3|Bootstrap3 notes]]&lt;br /&gt;
&lt;br /&gt;
=== Session 3 ===&lt;br /&gt;
&lt;br /&gt;
* [https://docs.google.com/document/d/11uOmoQdxZAy3dh-BHs7pkFFHyoUlQ8PD2SdxuhlDsK0/edit | HTML5 Player notes]&lt;br /&gt;
* [[Add-ons trust model]]&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Hackfest_UK_2014&amp;diff=44472</id>
		<title>Hackfest UK 2014</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Hackfest_UK_2014&amp;diff=44472"/>
		<updated>2014-04-17T13:11:28Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: /* Session 3 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[file:Hackfest_Logo_-_Narrow.png|202|right]]&lt;br /&gt;
&lt;br /&gt;
[[Developer meetings]] &amp;gt; UK Hackfest April 2014&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| When&lt;br /&gt;
| Thu 14 April, 2014&lt;br /&gt;
|-&lt;br /&gt;
| Where&lt;br /&gt;
| Moodlemoot Edinburgh, UK&lt;br /&gt;
|-&lt;br /&gt;
| Alternate name&lt;br /&gt;
| Haven&#039;t come up with one yet&lt;br /&gt;
|-&lt;br /&gt;
| Hashtag&lt;br /&gt;
| [https://twitter.com/search/%23mootuk14 #mootuk14]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== What happened? ==&lt;br /&gt;
&lt;br /&gt;
A Hackfest brings together Moodle developers to brainstorm future Moodle developments.&lt;br /&gt;
&lt;br /&gt;
A description of the activities at the Hackfest will be added here.&lt;br /&gt;
&lt;br /&gt;
== Group notes ==&lt;br /&gt;
&lt;br /&gt;
===Tools===&lt;br /&gt;
&lt;br /&gt;
* Php Xref&lt;br /&gt;
* Xdebug + IDE&lt;br /&gt;
* XHprof&lt;br /&gt;
* codechecker&lt;br /&gt;
* PHPUnit&lt;br /&gt;
* MDK&lt;br /&gt;
* Moosh&lt;br /&gt;
* Grunt&lt;br /&gt;
* Git&lt;br /&gt;
&lt;br /&gt;
==Specifications==&lt;br /&gt;
&lt;br /&gt;
Specifications from subsequent work will be liked from here&lt;br /&gt;
&lt;br /&gt;
=== Session 1 ===&lt;br /&gt;
&lt;br /&gt;
* [https://docs.google.com/document/d/1iisKZks8e_JqjpGTXip1dJ9hS29QsGG4mSomKcFGVRg/edit?usp=sharing Moodle element library notes]&lt;br /&gt;
*[https://docs.google.com/document/d/1mlJjxewBOaZyQ14C0KIe5aV38hCmWF5aIQldlw-EwmU/edit?usp=sharing Moodle Analytics Notes]&lt;br /&gt;
* [[Hackfest_UK_2014/LTI|LTI Usability Improvements notes]]&lt;br /&gt;
&lt;br /&gt;
=== Session 2 ===&lt;br /&gt;
&lt;br /&gt;
* [https://docs.google.com/document/d/1XjiVY3ax9EuZ7gneofJR9z330rdI9bhD0yoOzt5tYRY/edit?usp=sharing Lesson refactoring notes]&lt;br /&gt;
* [[Hackfest_UK_2014/Email Logging|Email Logging Functionality and Reporting notes]]&lt;br /&gt;
* [[Hackfest_UK_2014/Bootstrap3|Bootstrap3 notes]]&lt;br /&gt;
&lt;br /&gt;
=== Session 3 ===&lt;br /&gt;
&lt;br /&gt;
* [https://docs.google.com/document/d/11uOmoQdxZAy3dh-BHs7pkFFHyoUlQ8PD2SdxuhlDsK0/edit|&amp;quot;HTML5 Player notes&amp;quot;]&lt;br /&gt;
* [[Add-ons trust model]]&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Hackfest_UK_2014&amp;diff=44469</id>
		<title>Hackfest UK 2014</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Hackfest_UK_2014&amp;diff=44469"/>
		<updated>2014-04-17T13:08:10Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: /* Session 3 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[file:Hackfest_Logo_-_Narrow.png|202|right]]&lt;br /&gt;
&lt;br /&gt;
[[Developer meetings]] &amp;gt; UK Hackfest April 2014&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| When&lt;br /&gt;
| Thu 14 April, 2014&lt;br /&gt;
|-&lt;br /&gt;
| Where&lt;br /&gt;
| Moodlemoot Edinburgh, UK&lt;br /&gt;
|-&lt;br /&gt;
| Alternate name&lt;br /&gt;
| Haven&#039;t come up with one yet&lt;br /&gt;
|-&lt;br /&gt;
| Hashtag&lt;br /&gt;
| [https://twitter.com/search/%23mootuk14 #mootuk14]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== What happened? ==&lt;br /&gt;
&lt;br /&gt;
A Hackfest brings together Moodle developers to brainstorm future Moodle developments.&lt;br /&gt;
&lt;br /&gt;
A description of the activities at the Hackfest will be added here.&lt;br /&gt;
&lt;br /&gt;
== Group notes ==&lt;br /&gt;
&lt;br /&gt;
===Tools===&lt;br /&gt;
&lt;br /&gt;
* Php Xref&lt;br /&gt;
* Xdebug + IDE&lt;br /&gt;
* XHprof&lt;br /&gt;
* codechecker&lt;br /&gt;
* PHPUnit&lt;br /&gt;
* MDK&lt;br /&gt;
* Moosh&lt;br /&gt;
* Grunt&lt;br /&gt;
* Git&lt;br /&gt;
&lt;br /&gt;
==Specifications==&lt;br /&gt;
&lt;br /&gt;
Specifications from subsequent work will be liked from here&lt;br /&gt;
&lt;br /&gt;
=== Session 1 ===&lt;br /&gt;
&lt;br /&gt;
* [https://docs.google.com/document/d/1iisKZks8e_JqjpGTXip1dJ9hS29QsGG4mSomKcFGVRg/edit?usp=sharing Moodle element library notes]&lt;br /&gt;
*[https://docs.google.com/document/d/1mlJjxewBOaZyQ14C0KIe5aV38hCmWF5aIQldlw-EwmU/edit?usp=sharing Moodle Analytics Notes]&lt;br /&gt;
* [[Hackfest_UK_2014/LTI|LTI Usability Improvements notes]]&lt;br /&gt;
&lt;br /&gt;
=== Session 2 ===&lt;br /&gt;
&lt;br /&gt;
* [https://docs.google.com/document/d/1XjiVY3ax9EuZ7gneofJR9z330rdI9bhD0yoOzt5tYRY/edit?usp=sharing Lesson refactoring notes]&lt;br /&gt;
* [[Hackfest_UK_2014/Email Logging|Email Logging Functionality and Reporting notes]]&lt;br /&gt;
* [[Hackfest_UK_2014/Bootstrap3|Bootstrap3 notes]]&lt;br /&gt;
&lt;br /&gt;
=== Session 3 ===&lt;br /&gt;
&lt;br /&gt;
* [https://docs.google.com/document/d/11uOmoQdxZAy3dh-BHs7pkFFHyoUlQ8PD2SdxuhlDsK0/edit|HTML5 Player notes]&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Hackfest_UK_2014&amp;diff=44468</id>
		<title>Hackfest UK 2014</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Hackfest_UK_2014&amp;diff=44468"/>
		<updated>2014-04-17T13:07:47Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: /* Session 3 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[file:Hackfest_Logo_-_Narrow.png|202|right]]&lt;br /&gt;
&lt;br /&gt;
[[Developer meetings]] &amp;gt; UK Hackfest April 2014&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| When&lt;br /&gt;
| Thu 14 April, 2014&lt;br /&gt;
|-&lt;br /&gt;
| Where&lt;br /&gt;
| Moodlemoot Edinburgh, UK&lt;br /&gt;
|-&lt;br /&gt;
| Alternate name&lt;br /&gt;
| Haven&#039;t come up with one yet&lt;br /&gt;
|-&lt;br /&gt;
| Hashtag&lt;br /&gt;
| [https://twitter.com/search/%23mootuk14 #mootuk14]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== What happened? ==&lt;br /&gt;
&lt;br /&gt;
A Hackfest brings together Moodle developers to brainstorm future Moodle developments.&lt;br /&gt;
&lt;br /&gt;
A description of the activities at the Hackfest will be added here.&lt;br /&gt;
&lt;br /&gt;
== Group notes ==&lt;br /&gt;
&lt;br /&gt;
===Tools===&lt;br /&gt;
&lt;br /&gt;
* Php Xref&lt;br /&gt;
* Xdebug + IDE&lt;br /&gt;
* XHprof&lt;br /&gt;
* codechecker&lt;br /&gt;
* PHPUnit&lt;br /&gt;
* MDK&lt;br /&gt;
* Moosh&lt;br /&gt;
* Grunt&lt;br /&gt;
* Git&lt;br /&gt;
&lt;br /&gt;
==Specifications==&lt;br /&gt;
&lt;br /&gt;
Specifications from subsequent work will be liked from here&lt;br /&gt;
&lt;br /&gt;
=== Session 1 ===&lt;br /&gt;
&lt;br /&gt;
* [https://docs.google.com/document/d/1iisKZks8e_JqjpGTXip1dJ9hS29QsGG4mSomKcFGVRg/edit?usp=sharing Moodle element library notes]&lt;br /&gt;
*[https://docs.google.com/document/d/1mlJjxewBOaZyQ14C0KIe5aV38hCmWF5aIQldlw-EwmU/edit?usp=sharing Moodle Analytics Notes]&lt;br /&gt;
* [[Hackfest_UK_2014/LTI|LTI Usability Improvements notes]]&lt;br /&gt;
&lt;br /&gt;
=== Session 2 ===&lt;br /&gt;
&lt;br /&gt;
* [https://docs.google.com/document/d/1XjiVY3ax9EuZ7gneofJR9z330rdI9bhD0yoOzt5tYRY/edit?usp=sharing Lesson refactoring notes]&lt;br /&gt;
* [[Hackfest_UK_2014/Email Logging|Email Logging Functionality and Reporting notes]]&lt;br /&gt;
* [[Hackfest_UK_2014/Bootstrap3|Bootstrap3 notes]]&lt;br /&gt;
&lt;br /&gt;
=== Session 3 ===&lt;br /&gt;
&lt;br /&gt;
[https://docs.google.com/document/d/11uOmoQdxZAy3dh-BHs7pkFFHyoUlQ8PD2SdxuhlDsK0/edit|HTML5 Player notes]&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=44395</id>
		<title>HTML5 player</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=44395"/>
		<updated>2014-04-16T14:09:22Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: /* Work around */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}&lt;br /&gt;
{{Infobox Project&lt;br /&gt;
|name = HTML5 Player with flash fallback&lt;br /&gt;
|state = In Development&lt;br /&gt;
|tracker = https://tracker.moodle.org/browse/MDL-38158&lt;br /&gt;
|discussion = https://moodle.org/mod/forum/discuss.php?d=222753#p1110024&lt;br /&gt;
|assignee = [https://tracker.moodle.org/secure/ViewProfile.jspa?name=kabalin Ruslan Kabalin]&lt;br /&gt;
}}&lt;br /&gt;
{{Moodle 2.x}}&lt;br /&gt;
&lt;br /&gt;
== Project goals ==&lt;br /&gt;
&lt;br /&gt;
The purpose of this document is to choose HTML5 player with flash fallback for integration in Moodle and plan its implementation.&lt;br /&gt;
&lt;br /&gt;
The aim of this change is to reach a consistent look of the player among different platforms and browsers, as well as making sure that player starts using flash if html5 is not supported by browser for the given format. Another aim is to improve accessibility and usability, enhance customisation.&lt;br /&gt;
&lt;br /&gt;
== Considerations ==&lt;br /&gt;
&lt;br /&gt;
* Usability of the player - is it easy to use it and intuitively understand how to use controls?&lt;br /&gt;
* Accessibility of the player - possibility of keyboard navigation, subtitles, support?&lt;br /&gt;
* Appearance of the player - can its interface be modified, themes support, RTL?&lt;br /&gt;
* Consistency among browsers - does player look the same?&lt;br /&gt;
* Audio support - can player handle HTML5 &amp;lt;audio&amp;gt; tag?&lt;br /&gt;
* Mobile platforms support - does player also work on iOS and Android?&lt;br /&gt;
* Streaming media support (including adaptive-bitrate delivery) - can player handle RTMP, Apple HLS, Adobe HDS, Microsoft HSS?&lt;br /&gt;
* Plugins support - can we use or develop community plugins easily?&lt;br /&gt;
* Embedding support - so users could post media content outside Moodle, if permitted.&lt;br /&gt;
* Maintainability of the links between the player and Moodle - how much work will we need to do every time we upgrade?&lt;br /&gt;
&lt;br /&gt;
== Candidates ==&lt;br /&gt;
&lt;br /&gt;
* [http://flowplayer.org/ Flowplayer HTML5]&lt;br /&gt;
* [http://www.videojs.com/ Video.JS]&lt;br /&gt;
* [http://www.projekktor.com/ Projekktor]&lt;br /&gt;
* ?Are there other alternatives?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! [[#Flowplayer_HTML5|Flowplayer HTML5]]&lt;br /&gt;
! [[#Video.JS|Video.JS]]&lt;br /&gt;
! [[#Projekktor|Projekktor]]&lt;br /&gt;
|-&lt;br /&gt;
! Accessible Player:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Keyboard control&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes (configurable)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Subtitles support&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via plugin)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Touch interface&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Appearance:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Skins&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* CSS customisation&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTL support&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
! Mobile platforms:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* iOS&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Android&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Streaming protocols:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTMP&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via playlist)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Adaptive HTTP&lt;br /&gt;
| HLS&lt;br /&gt;
| HLS (via plugin)&lt;br /&gt;
| HLS (via playlist)&lt;br /&gt;
|-&lt;br /&gt;
! Audio player&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Embedding support&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (configurable)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via addThis plugin)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via plugin)&lt;br /&gt;
|-&lt;br /&gt;
! License&lt;br /&gt;
| GPL v3 (with additional terms)&lt;br /&gt;
| Apache 2&lt;br /&gt;
| GPL v3&lt;br /&gt;
|-&lt;br /&gt;
! JS library&lt;br /&gt;
| jQuery&lt;br /&gt;
| -&lt;br /&gt;
| jQuery&lt;br /&gt;
|-&lt;br /&gt;
! Plugins infrastructure&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Flash fallback player&lt;br /&gt;
| Flowplayer Flash&lt;br /&gt;
| video-js flash&lt;br /&gt;
| StobeMediaPlayback (but can be jarisplayer or some other).&lt;br /&gt;
|-&lt;br /&gt;
! API&lt;br /&gt;
| Yes (plus window.flowplayer object)&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Flowplayer HTML5 ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* Good looking player, resembles existing flash flowplayer in Moodle (with &amp;quot;functional&amp;quot; skin)&lt;br /&gt;
* Extensive customisation (via CSS3 skins and configuration object)&lt;br /&gt;
* Streaming support (RTMP, HLS)&lt;br /&gt;
* Good accessibility features&lt;br /&gt;
* Configurable embedding functionality&lt;br /&gt;
* Existing flash flowplayer can be configured for fallback (the appearance of player will not be affected).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Require jQuery for functioning&lt;br /&gt;
* Flowplayer logo remains on screen&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using wrapper around &amp;lt;video&amp;gt;.&lt;br /&gt;
* width and height attributes in video tag are ignored, player size is configured via wrapper size only.&lt;br /&gt;
* RTMP server connection is configured via data-rtmp attribute in wrapper or player init config parameter, actual path the file specified in src attribute of source item.&lt;br /&gt;
* &amp;lt;source type=&amp;quot;video/flash&amp;quot;... dummy MIME type to force using plash player for whatever content.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Plugins infrastructure&lt;br /&gt;
* No audio support&lt;br /&gt;
&lt;br /&gt;
=== Video.JS ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Extensive API.&lt;br /&gt;
* No extra JS library needed.&lt;br /&gt;
* Many plugins.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Poor documentation&lt;br /&gt;
* RTMP requires non-standard MIME.&lt;br /&gt;
* Android and iOS override Video.JS with own player, when not overridden, content is not playing.&lt;br /&gt;
* No RTL.&lt;br /&gt;
* HLS support via plugin (many files to include, external contributor see https://github.com/videojs/videojs-contrib-hls).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* RTMP server connection and path specified as single URI in src attribute of source item, &#039;&amp;amp;&#039; character is used as server connection and path divider.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Embedded HLS support.&lt;br /&gt;
&lt;br /&gt;
=== Projekktor ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Well documented API.&lt;br /&gt;
* Media RSS support.&lt;br /&gt;
* Possibility to choose flash player for fallback (included by default are StrobeMediaPlayback and Jarisplayer, both Open Source).&lt;br /&gt;
* Platform preference order selection (e.g. browser, ios, android, flash, native).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Uses flash where it is not supposed to (e.g. mp4 in Chrome).&lt;br /&gt;
* Issues on ios and android (suggests to download file when play button is pressed).&lt;br /&gt;
* RTMP only work if defined via playlist rather than in &amp;lt;source&amp;gt; tags.&lt;br /&gt;
* Subtitles plugin is not free.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* Make sure &amp;lt;video&amp;gt; tag has class attribute with &#039;projekktor&#039; value (even if you initialise it by ID of the element), player will not work properly otherwise.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Cross-browser support ==&lt;br /&gt;
&lt;br /&gt;
=== Method ===&lt;br /&gt;
Compatibility checks were done manually by accessing the sample page using different browsers and platforms. Sample page contained the list of identical player instances, initialised for each &amp;lt;video&amp;gt; definition with a &amp;lt;source&amp;gt; of particular format: mp4, webm, ogg, flv. Streaming support was checked by setting up a &amp;lt;video&amp;gt; container with two sources of the same video, one was HLS (Apple HTTP Live Streaming) stream for browsers and platforms that support html5 video streaming, another one was RTMP which is played using flash engine and supposed to be used in case if HLS is not supported.&lt;br /&gt;
&lt;br /&gt;
=== Sample Pages ===&lt;br /&gt;
&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=flowplayer Flowplayer HTML5] version 5.4.6.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=videojs Video.JS] version 4.4.1.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=projekktor Projekktor] version 1.3.09.&lt;br /&gt;
&lt;br /&gt;
=== Source ===&lt;br /&gt;
&lt;br /&gt;
Source of testing page is hosted on [https://github.com/kabalin/test-html5-players/blob/master/players.php github]. The actual source of the html page can be viewed in browser.&lt;br /&gt;
&lt;br /&gt;
=== Discussion ===&lt;br /&gt;
&lt;br /&gt;
The players comparison that has been carried out demonstrated that &amp;quot;least hassle&amp;quot; player is Flowplayer. Despite some drawbacks listed in [[#Flowplayer_HTML5|corresponding section above]], it is clearly a winner as it works as expected and according to documentation for all browsers and platforms I had chance to test it. This is the only player that supports RTL layout, display platform incompatibility message prior to attempt to play, and was simple to configure (no undocumented tricks that I had to figure out to make it work). Both VideoJS and Projekktor do now perform properly in all cases. Among those two, I personally prefer Projekktor more for its extensive API, plugins infrastructure and configuration flexibility. However problems on mobile platforms and flash fallback inconsistency make them unreliable at this stage.&lt;br /&gt;
&lt;br /&gt;
=== Compatibility results ===&lt;br /&gt;
&lt;br /&gt;
The table was populated using Flowplayer as others do not perform good enough with some formats and platforms, e.g. VideoJS allow mobile platform player to override itself, Projekktor does not always use HTML5 where browser clearly can handle it (supported in native mode and Flowplayer).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Browser&lt;br /&gt;
! mp4&lt;br /&gt;
! webm&lt;br /&gt;
! ogg&lt;br /&gt;
! flv&lt;br /&gt;
! RTMP/HLS*&lt;br /&gt;
|-&lt;br /&gt;
! Windows 7&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Firefox 27.0.1&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 12.16&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 5.1.7&lt;br /&gt;
| flash&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Internet Explorer 11.0.9600.x&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Linux (Debian Wheezy)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.115&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! OSX 10.9&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 7.0 (9537.71)&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 phone (CyanogenMod, no flash)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 tablet (GalaxyTab2, flash app 11.1.115.36)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 19.0.1340.x&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
! iPhone 4S (6.1.3)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! iPad 4 (7.0.6)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;small&amp;gt;* For HLS/RTMP, html5 in the table means HLS has been used, flash means player fell back and used RTMP.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sub Tasks ==&lt;br /&gt;
&lt;br /&gt;
In initial stage FlowPlayer HTML5 (or any other) will handle all existing HTML5 Video extensions as per core_media_player_html5video class, plus m3u8 (HLS). It will also be possible optionally to make flash files handled by HTML5 Video player as well (possibility of using existing flash FlowPlayer for flv files will remain).&lt;br /&gt;
&lt;br /&gt;
== Mock-Ups/Prototypes ==&lt;br /&gt;
&lt;br /&gt;
See [[#Sample_Pages|Sample pages]] section.&lt;br /&gt;
&lt;br /&gt;
== Workaround ==&lt;br /&gt;
&lt;br /&gt;
As intermediate solution, if you require player consistency throughout all browsers and platforms, you may consider using JW Player filter: https://github.com/lucisgit/moodle-filter_jwplayer Notice, that JW Player is not free for commercial use.&lt;br /&gt;
&lt;br /&gt;
== Related Tracker Issues ==&lt;br /&gt;
* MDL-38158&lt;br /&gt;
&lt;br /&gt;
== Useful links ==&lt;br /&gt;
* http://praegnanz.de/html5video/&lt;br /&gt;
* http://html5video.org/wiki/HTML5_Video_Player_Comparison&lt;br /&gt;
* http://www.streamingmedia.com/Articles/Editorial/Featured-Articles/Choosing-a-Video-Player-Features-and-Specs-for-the-Top-Five-94188.aspx&lt;br /&gt;
&lt;br /&gt;
[[Category:Project]]&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=44394</id>
		<title>HTML5 player</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=44394"/>
		<updated>2014-04-16T14:08:57Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: /* Alternatives */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}&lt;br /&gt;
{{Infobox Project&lt;br /&gt;
|name = HTML5 Player with flash fallback&lt;br /&gt;
|state = In Development&lt;br /&gt;
|tracker = https://tracker.moodle.org/browse/MDL-38158&lt;br /&gt;
|discussion = https://moodle.org/mod/forum/discuss.php?d=222753#p1110024&lt;br /&gt;
|assignee = [https://tracker.moodle.org/secure/ViewProfile.jspa?name=kabalin Ruslan Kabalin]&lt;br /&gt;
}}&lt;br /&gt;
{{Moodle 2.x}}&lt;br /&gt;
&lt;br /&gt;
== Project goals ==&lt;br /&gt;
&lt;br /&gt;
The purpose of this document is to choose HTML5 player with flash fallback for integration in Moodle and plan its implementation.&lt;br /&gt;
&lt;br /&gt;
The aim of this change is to reach a consistent look of the player among different platforms and browsers, as well as making sure that player starts using flash if html5 is not supported by browser for the given format. Another aim is to improve accessibility and usability, enhance customisation.&lt;br /&gt;
&lt;br /&gt;
== Considerations ==&lt;br /&gt;
&lt;br /&gt;
* Usability of the player - is it easy to use it and intuitively understand how to use controls?&lt;br /&gt;
* Accessibility of the player - possibility of keyboard navigation, subtitles, support?&lt;br /&gt;
* Appearance of the player - can its interface be modified, themes support, RTL?&lt;br /&gt;
* Consistency among browsers - does player look the same?&lt;br /&gt;
* Audio support - can player handle HTML5 &amp;lt;audio&amp;gt; tag?&lt;br /&gt;
* Mobile platforms support - does player also work on iOS and Android?&lt;br /&gt;
* Streaming media support (including adaptive-bitrate delivery) - can player handle RTMP, Apple HLS, Adobe HDS, Microsoft HSS?&lt;br /&gt;
* Plugins support - can we use or develop community plugins easily?&lt;br /&gt;
* Embedding support - so users could post media content outside Moodle, if permitted.&lt;br /&gt;
* Maintainability of the links between the player and Moodle - how much work will we need to do every time we upgrade?&lt;br /&gt;
&lt;br /&gt;
== Candidates ==&lt;br /&gt;
&lt;br /&gt;
* [http://flowplayer.org/ Flowplayer HTML5]&lt;br /&gt;
* [http://www.videojs.com/ Video.JS]&lt;br /&gt;
* [http://www.projekktor.com/ Projekktor]&lt;br /&gt;
* ?Are there other alternatives?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! [[#Flowplayer_HTML5|Flowplayer HTML5]]&lt;br /&gt;
! [[#Video.JS|Video.JS]]&lt;br /&gt;
! [[#Projekktor|Projekktor]]&lt;br /&gt;
|-&lt;br /&gt;
! Accessible Player:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Keyboard control&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes (configurable)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Subtitles support&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via plugin)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Touch interface&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Appearance:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Skins&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* CSS customisation&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTL support&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
! Mobile platforms:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* iOS&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Android&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Streaming protocols:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTMP&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via playlist)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Adaptive HTTP&lt;br /&gt;
| HLS&lt;br /&gt;
| HLS (via plugin)&lt;br /&gt;
| HLS (via playlist)&lt;br /&gt;
|-&lt;br /&gt;
! Audio player&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Embedding support&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (configurable)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via addThis plugin)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via plugin)&lt;br /&gt;
|-&lt;br /&gt;
! License&lt;br /&gt;
| GPL v3 (with additional terms)&lt;br /&gt;
| Apache 2&lt;br /&gt;
| GPL v3&lt;br /&gt;
|-&lt;br /&gt;
! JS library&lt;br /&gt;
| jQuery&lt;br /&gt;
| -&lt;br /&gt;
| jQuery&lt;br /&gt;
|-&lt;br /&gt;
! Plugins infrastructure&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Flash fallback player&lt;br /&gt;
| Flowplayer Flash&lt;br /&gt;
| video-js flash&lt;br /&gt;
| StobeMediaPlayback (but can be jarisplayer or some other).&lt;br /&gt;
|-&lt;br /&gt;
! API&lt;br /&gt;
| Yes (plus window.flowplayer object)&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Flowplayer HTML5 ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* Good looking player, resembles existing flash flowplayer in Moodle (with &amp;quot;functional&amp;quot; skin)&lt;br /&gt;
* Extensive customisation (via CSS3 skins and configuration object)&lt;br /&gt;
* Streaming support (RTMP, HLS)&lt;br /&gt;
* Good accessibility features&lt;br /&gt;
* Configurable embedding functionality&lt;br /&gt;
* Existing flash flowplayer can be configured for fallback (the appearance of player will not be affected).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Require jQuery for functioning&lt;br /&gt;
* Flowplayer logo remains on screen&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using wrapper around &amp;lt;video&amp;gt;.&lt;br /&gt;
* width and height attributes in video tag are ignored, player size is configured via wrapper size only.&lt;br /&gt;
* RTMP server connection is configured via data-rtmp attribute in wrapper or player init config parameter, actual path the file specified in src attribute of source item.&lt;br /&gt;
* &amp;lt;source type=&amp;quot;video/flash&amp;quot;... dummy MIME type to force using plash player for whatever content.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Plugins infrastructure&lt;br /&gt;
* No audio support&lt;br /&gt;
&lt;br /&gt;
=== Video.JS ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Extensive API.&lt;br /&gt;
* No extra JS library needed.&lt;br /&gt;
* Many plugins.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Poor documentation&lt;br /&gt;
* RTMP requires non-standard MIME.&lt;br /&gt;
* Android and iOS override Video.JS with own player, when not overridden, content is not playing.&lt;br /&gt;
* No RTL.&lt;br /&gt;
* HLS support via plugin (many files to include, external contributor see https://github.com/videojs/videojs-contrib-hls).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* RTMP server connection and path specified as single URI in src attribute of source item, &#039;&amp;amp;&#039; character is used as server connection and path divider.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Embedded HLS support.&lt;br /&gt;
&lt;br /&gt;
=== Projekktor ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Well documented API.&lt;br /&gt;
* Media RSS support.&lt;br /&gt;
* Possibility to choose flash player for fallback (included by default are StrobeMediaPlayback and Jarisplayer, both Open Source).&lt;br /&gt;
* Platform preference order selection (e.g. browser, ios, android, flash, native).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Uses flash where it is not supposed to (e.g. mp4 in Chrome).&lt;br /&gt;
* Issues on ios and android (suggests to download file when play button is pressed).&lt;br /&gt;
* RTMP only work if defined via playlist rather than in &amp;lt;source&amp;gt; tags.&lt;br /&gt;
* Subtitles plugin is not free.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* Make sure &amp;lt;video&amp;gt; tag has class attribute with &#039;projekktor&#039; value (even if you initialise it by ID of the element), player will not work properly otherwise.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Cross-browser support ==&lt;br /&gt;
&lt;br /&gt;
=== Method ===&lt;br /&gt;
Compatibility checks were done manually by accessing the sample page using different browsers and platforms. Sample page contained the list of identical player instances, initialised for each &amp;lt;video&amp;gt; definition with a &amp;lt;source&amp;gt; of particular format: mp4, webm, ogg, flv. Streaming support was checked by setting up a &amp;lt;video&amp;gt; container with two sources of the same video, one was HLS (Apple HTTP Live Streaming) stream for browsers and platforms that support html5 video streaming, another one was RTMP which is played using flash engine and supposed to be used in case if HLS is not supported.&lt;br /&gt;
&lt;br /&gt;
=== Sample Pages ===&lt;br /&gt;
&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=flowplayer Flowplayer HTML5] version 5.4.6.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=videojs Video.JS] version 4.4.1.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=projekktor Projekktor] version 1.3.09.&lt;br /&gt;
&lt;br /&gt;
=== Source ===&lt;br /&gt;
&lt;br /&gt;
Source of testing page is hosted on [https://github.com/kabalin/test-html5-players/blob/master/players.php github]. The actual source of the html page can be viewed in browser.&lt;br /&gt;
&lt;br /&gt;
=== Discussion ===&lt;br /&gt;
&lt;br /&gt;
The players comparison that has been carried out demonstrated that &amp;quot;least hassle&amp;quot; player is Flowplayer. Despite some drawbacks listed in [[#Flowplayer_HTML5|corresponding section above]], it is clearly a winner as it works as expected and according to documentation for all browsers and platforms I had chance to test it. This is the only player that supports RTL layout, display platform incompatibility message prior to attempt to play, and was simple to configure (no undocumented tricks that I had to figure out to make it work). Both VideoJS and Projekktor do now perform properly in all cases. Among those two, I personally prefer Projekktor more for its extensive API, plugins infrastructure and configuration flexibility. However problems on mobile platforms and flash fallback inconsistency make them unreliable at this stage.&lt;br /&gt;
&lt;br /&gt;
=== Compatibility results ===&lt;br /&gt;
&lt;br /&gt;
The table was populated using Flowplayer as others do not perform good enough with some formats and platforms, e.g. VideoJS allow mobile platform player to override itself, Projekktor does not always use HTML5 where browser clearly can handle it (supported in native mode and Flowplayer).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Browser&lt;br /&gt;
! mp4&lt;br /&gt;
! webm&lt;br /&gt;
! ogg&lt;br /&gt;
! flv&lt;br /&gt;
! RTMP/HLS*&lt;br /&gt;
|-&lt;br /&gt;
! Windows 7&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Firefox 27.0.1&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 12.16&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 5.1.7&lt;br /&gt;
| flash&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Internet Explorer 11.0.9600.x&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Linux (Debian Wheezy)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.115&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! OSX 10.9&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 7.0 (9537.71)&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 phone (CyanogenMod, no flash)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 tablet (GalaxyTab2, flash app 11.1.115.36)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 19.0.1340.x&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
! iPhone 4S (6.1.3)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! iPad 4 (7.0.6)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;small&amp;gt;* For HLS/RTMP, html5 in the table means HLS has been used, flash means player fell back and used RTMP.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sub Tasks ==&lt;br /&gt;
&lt;br /&gt;
In initial stage FlowPlayer HTML5 (or any other) will handle all existing HTML5 Video extensions as per core_media_player_html5video class, plus m3u8 (HLS). It will also be possible optionally to make flash files handled by HTML5 Video player as well (possibility of using existing flash FlowPlayer for flv files will remain).&lt;br /&gt;
&lt;br /&gt;
== Mock-Ups/Prototypes ==&lt;br /&gt;
&lt;br /&gt;
See [[#Sample_Pages|Sample pages]] section.&lt;br /&gt;
&lt;br /&gt;
== Work around ==&lt;br /&gt;
&lt;br /&gt;
As intermediate solution, if you require player consistency throughout all browsers and platforms, you may consider using JW Player filter: https://github.com/lucisgit/moodle-filter_jwplayer Notice, that JW Player is not free for commercial use.&lt;br /&gt;
&lt;br /&gt;
== Related Tracker Issues ==&lt;br /&gt;
* MDL-38158&lt;br /&gt;
&lt;br /&gt;
== Useful links ==&lt;br /&gt;
* http://praegnanz.de/html5video/&lt;br /&gt;
* http://html5video.org/wiki/HTML5_Video_Player_Comparison&lt;br /&gt;
* http://www.streamingmedia.com/Articles/Editorial/Featured-Articles/Choosing-a-Video-Player-Features-and-Specs-for-the-Top-Five-94188.aspx&lt;br /&gt;
&lt;br /&gt;
[[Category:Project]]&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=44393</id>
		<title>HTML5 player</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=44393"/>
		<updated>2014-04-16T14:08:23Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}&lt;br /&gt;
{{Infobox Project&lt;br /&gt;
|name = HTML5 Player with flash fallback&lt;br /&gt;
|state = In Development&lt;br /&gt;
|tracker = https://tracker.moodle.org/browse/MDL-38158&lt;br /&gt;
|discussion = https://moodle.org/mod/forum/discuss.php?d=222753#p1110024&lt;br /&gt;
|assignee = [https://tracker.moodle.org/secure/ViewProfile.jspa?name=kabalin Ruslan Kabalin]&lt;br /&gt;
}}&lt;br /&gt;
{{Moodle 2.x}}&lt;br /&gt;
&lt;br /&gt;
== Project goals ==&lt;br /&gt;
&lt;br /&gt;
The purpose of this document is to choose HTML5 player with flash fallback for integration in Moodle and plan its implementation.&lt;br /&gt;
&lt;br /&gt;
The aim of this change is to reach a consistent look of the player among different platforms and browsers, as well as making sure that player starts using flash if html5 is not supported by browser for the given format. Another aim is to improve accessibility and usability, enhance customisation.&lt;br /&gt;
&lt;br /&gt;
== Considerations ==&lt;br /&gt;
&lt;br /&gt;
* Usability of the player - is it easy to use it and intuitively understand how to use controls?&lt;br /&gt;
* Accessibility of the player - possibility of keyboard navigation, subtitles, support?&lt;br /&gt;
* Appearance of the player - can its interface be modified, themes support, RTL?&lt;br /&gt;
* Consistency among browsers - does player look the same?&lt;br /&gt;
* Audio support - can player handle HTML5 &amp;lt;audio&amp;gt; tag?&lt;br /&gt;
* Mobile platforms support - does player also work on iOS and Android?&lt;br /&gt;
* Streaming media support (including adaptive-bitrate delivery) - can player handle RTMP, Apple HLS, Adobe HDS, Microsoft HSS?&lt;br /&gt;
* Plugins support - can we use or develop community plugins easily?&lt;br /&gt;
* Embedding support - so users could post media content outside Moodle, if permitted.&lt;br /&gt;
* Maintainability of the links between the player and Moodle - how much work will we need to do every time we upgrade?&lt;br /&gt;
&lt;br /&gt;
== Candidates ==&lt;br /&gt;
&lt;br /&gt;
* [http://flowplayer.org/ Flowplayer HTML5]&lt;br /&gt;
* [http://www.videojs.com/ Video.JS]&lt;br /&gt;
* [http://www.projekktor.com/ Projekktor]&lt;br /&gt;
* ?Are there other alternatives?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! [[#Flowplayer_HTML5|Flowplayer HTML5]]&lt;br /&gt;
! [[#Video.JS|Video.JS]]&lt;br /&gt;
! [[#Projekktor|Projekktor]]&lt;br /&gt;
|-&lt;br /&gt;
! Accessible Player:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Keyboard control&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes (configurable)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Subtitles support&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via plugin)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Touch interface&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Appearance:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Skins&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* CSS customisation&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTL support&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
! Mobile platforms:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* iOS&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Android&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Streaming protocols:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTMP&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via playlist)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Adaptive HTTP&lt;br /&gt;
| HLS&lt;br /&gt;
| HLS (via plugin)&lt;br /&gt;
| HLS (via playlist)&lt;br /&gt;
|-&lt;br /&gt;
! Audio player&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Embedding support&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (configurable)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via addThis plugin)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via plugin)&lt;br /&gt;
|-&lt;br /&gt;
! License&lt;br /&gt;
| GPL v3 (with additional terms)&lt;br /&gt;
| Apache 2&lt;br /&gt;
| GPL v3&lt;br /&gt;
|-&lt;br /&gt;
! JS library&lt;br /&gt;
| jQuery&lt;br /&gt;
| -&lt;br /&gt;
| jQuery&lt;br /&gt;
|-&lt;br /&gt;
! Plugins infrastructure&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Flash fallback player&lt;br /&gt;
| Flowplayer Flash&lt;br /&gt;
| video-js flash&lt;br /&gt;
| StobeMediaPlayback (but can be jarisplayer or some other).&lt;br /&gt;
|-&lt;br /&gt;
! API&lt;br /&gt;
| Yes (plus window.flowplayer object)&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Flowplayer HTML5 ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* Good looking player, resembles existing flash flowplayer in Moodle (with &amp;quot;functional&amp;quot; skin)&lt;br /&gt;
* Extensive customisation (via CSS3 skins and configuration object)&lt;br /&gt;
* Streaming support (RTMP, HLS)&lt;br /&gt;
* Good accessibility features&lt;br /&gt;
* Configurable embedding functionality&lt;br /&gt;
* Existing flash flowplayer can be configured for fallback (the appearance of player will not be affected).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Require jQuery for functioning&lt;br /&gt;
* Flowplayer logo remains on screen&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using wrapper around &amp;lt;video&amp;gt;.&lt;br /&gt;
* width and height attributes in video tag are ignored, player size is configured via wrapper size only.&lt;br /&gt;
* RTMP server connection is configured via data-rtmp attribute in wrapper or player init config parameter, actual path the file specified in src attribute of source item.&lt;br /&gt;
* &amp;lt;source type=&amp;quot;video/flash&amp;quot;... dummy MIME type to force using plash player for whatever content.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Plugins infrastructure&lt;br /&gt;
* No audio support&lt;br /&gt;
&lt;br /&gt;
=== Video.JS ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Extensive API.&lt;br /&gt;
* No extra JS library needed.&lt;br /&gt;
* Many plugins.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Poor documentation&lt;br /&gt;
* RTMP requires non-standard MIME.&lt;br /&gt;
* Android and iOS override Video.JS with own player, when not overridden, content is not playing.&lt;br /&gt;
* No RTL.&lt;br /&gt;
* HLS support via plugin (many files to include, external contributor see https://github.com/videojs/videojs-contrib-hls).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* RTMP server connection and path specified as single URI in src attribute of source item, &#039;&amp;amp;&#039; character is used as server connection and path divider.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Embedded HLS support.&lt;br /&gt;
&lt;br /&gt;
=== Projekktor ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Well documented API.&lt;br /&gt;
* Media RSS support.&lt;br /&gt;
* Possibility to choose flash player for fallback (included by default are StrobeMediaPlayback and Jarisplayer, both Open Source).&lt;br /&gt;
* Platform preference order selection (e.g. browser, ios, android, flash, native).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Uses flash where it is not supposed to (e.g. mp4 in Chrome).&lt;br /&gt;
* Issues on ios and android (suggests to download file when play button is pressed).&lt;br /&gt;
* RTMP only work if defined via playlist rather than in &amp;lt;source&amp;gt; tags.&lt;br /&gt;
* Subtitles plugin is not free.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* Make sure &amp;lt;video&amp;gt; tag has class attribute with &#039;projekktor&#039; value (even if you initialise it by ID of the element), player will not work properly otherwise.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Cross-browser support ==&lt;br /&gt;
&lt;br /&gt;
=== Method ===&lt;br /&gt;
Compatibility checks were done manually by accessing the sample page using different browsers and platforms. Sample page contained the list of identical player instances, initialised for each &amp;lt;video&amp;gt; definition with a &amp;lt;source&amp;gt; of particular format: mp4, webm, ogg, flv. Streaming support was checked by setting up a &amp;lt;video&amp;gt; container with two sources of the same video, one was HLS (Apple HTTP Live Streaming) stream for browsers and platforms that support html5 video streaming, another one was RTMP which is played using flash engine and supposed to be used in case if HLS is not supported.&lt;br /&gt;
&lt;br /&gt;
=== Sample Pages ===&lt;br /&gt;
&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=flowplayer Flowplayer HTML5] version 5.4.6.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=videojs Video.JS] version 4.4.1.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=projekktor Projekktor] version 1.3.09.&lt;br /&gt;
&lt;br /&gt;
=== Source ===&lt;br /&gt;
&lt;br /&gt;
Source of testing page is hosted on [https://github.com/kabalin/test-html5-players/blob/master/players.php github]. The actual source of the html page can be viewed in browser.&lt;br /&gt;
&lt;br /&gt;
=== Discussion ===&lt;br /&gt;
&lt;br /&gt;
The players comparison that has been carried out demonstrated that &amp;quot;least hassle&amp;quot; player is Flowplayer. Despite some drawbacks listed in [[#Flowplayer_HTML5|corresponding section above]], it is clearly a winner as it works as expected and according to documentation for all browsers and platforms I had chance to test it. This is the only player that supports RTL layout, display platform incompatibility message prior to attempt to play, and was simple to configure (no undocumented tricks that I had to figure out to make it work). Both VideoJS and Projekktor do now perform properly in all cases. Among those two, I personally prefer Projekktor more for its extensive API, plugins infrastructure and configuration flexibility. However problems on mobile platforms and flash fallback inconsistency make them unreliable at this stage.&lt;br /&gt;
&lt;br /&gt;
=== Compatibility results ===&lt;br /&gt;
&lt;br /&gt;
The table was populated using Flowplayer as others do not perform good enough with some formats and platforms, e.g. VideoJS allow mobile platform player to override itself, Projekktor does not always use HTML5 where browser clearly can handle it (supported in native mode and Flowplayer).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Browser&lt;br /&gt;
! mp4&lt;br /&gt;
! webm&lt;br /&gt;
! ogg&lt;br /&gt;
! flv&lt;br /&gt;
! RTMP/HLS*&lt;br /&gt;
|-&lt;br /&gt;
! Windows 7&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Firefox 27.0.1&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 12.16&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 5.1.7&lt;br /&gt;
| flash&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Internet Explorer 11.0.9600.x&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Linux (Debian Wheezy)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.115&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! OSX 10.9&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 7.0 (9537.71)&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 phone (CyanogenMod, no flash)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 tablet (GalaxyTab2, flash app 11.1.115.36)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 19.0.1340.x&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
! iPhone 4S (6.1.3)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! iPad 4 (7.0.6)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;small&amp;gt;* For HLS/RTMP, html5 in the table means HLS has been used, flash means player fell back and used RTMP.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sub Tasks ==&lt;br /&gt;
&lt;br /&gt;
In initial stage FlowPlayer HTML5 (or any other) will handle all existing HTML5 Video extensions as per core_media_player_html5video class, plus m3u8 (HLS). It will also be possible optionally to make flash files handled by HTML5 Video player as well (possibility of using existing flash FlowPlayer for flv files will remain).&lt;br /&gt;
&lt;br /&gt;
== Mock-Ups/Prototypes ==&lt;br /&gt;
&lt;br /&gt;
See [[#Sample_Pages|Sample pages]] section.&lt;br /&gt;
&lt;br /&gt;
== Alternatives ==&lt;br /&gt;
&lt;br /&gt;
As intermediate solution, if you require player consistency throughout all browsers and platforms, you may consider using JW Player filter: https://github.com/lucisgit/moodle-filter_jwplayer Notice, that JW Player is not free for commercial use.&lt;br /&gt;
&lt;br /&gt;
== Related Tracker Issues ==&lt;br /&gt;
* MDL-38158&lt;br /&gt;
&lt;br /&gt;
== Useful links ==&lt;br /&gt;
* http://praegnanz.de/html5video/&lt;br /&gt;
* http://html5video.org/wiki/HTML5_Video_Player_Comparison&lt;br /&gt;
* http://www.streamingmedia.com/Articles/Editorial/Featured-Articles/Choosing-a-Video-Player-Features-and-Specs-for-the-Top-Five-94188.aspx&lt;br /&gt;
&lt;br /&gt;
[[Category:Project]]&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=44144</id>
		<title>HTML5 player</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=44144"/>
		<updated>2014-03-10T15:47:49Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: /* Project goals */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}&lt;br /&gt;
{{Infobox Project&lt;br /&gt;
|name = HTML5 Player with flash fallback&lt;br /&gt;
|state = In Development&lt;br /&gt;
|tracker = https://tracker.moodle.org/browse/MDL-38158&lt;br /&gt;
|discussion = https://moodle.org/mod/forum/discuss.php?d=222753#p1110024&lt;br /&gt;
|assignee = [https://tracker.moodle.org/secure/ViewProfile.jspa?name=kabalin Ruslan Kabalin]&lt;br /&gt;
}}&lt;br /&gt;
{{Moodle 2.x}}&lt;br /&gt;
&lt;br /&gt;
== Project goals ==&lt;br /&gt;
&lt;br /&gt;
The purpose of this document is to choose HTML5 player with flash fallback for integration in Moodle and plan its implementation.&lt;br /&gt;
&lt;br /&gt;
The aim of this change is to reach a consistent look of the player among different platforms and browsers, as well as making sure that player starts using flash if html5 is not supported by browser for the given format. Another aim is to improve accessibility and usability, enhance customisation.&lt;br /&gt;
&lt;br /&gt;
== Considerations ==&lt;br /&gt;
&lt;br /&gt;
* Usability of the player - is it easy to use it and intuitively understand how to use controls?&lt;br /&gt;
* Accessibility of the player - possibility of keyboard navigation, subtitles, support?&lt;br /&gt;
* Appearance of the player - can its interface be modified, themes support, RTL?&lt;br /&gt;
* Consistency among browsers - does player look the same?&lt;br /&gt;
* Audio support - can player handle HTML5 &amp;lt;audio&amp;gt; tag?&lt;br /&gt;
* Mobile platforms support - does player also work on iOS and Android?&lt;br /&gt;
* Streaming media support (including adaptive-bitrate delivery) - can player handle RTMP, Apple HLS, Adobe HDS, Microsoft HSS?&lt;br /&gt;
* Plugins support - can we use or develop community plugins easily?&lt;br /&gt;
* Embedding support - so users could post media content outside Moodle, if permitted.&lt;br /&gt;
* Maintainability of the links between the player and Moodle - how much work will we need to do every time we upgrade?&lt;br /&gt;
&lt;br /&gt;
== Candidates ==&lt;br /&gt;
&lt;br /&gt;
* [http://flowplayer.org/ Flowplayer HTML5]&lt;br /&gt;
* [http://www.videojs.com/ Video.JS]&lt;br /&gt;
* [http://www.projekktor.com/ Projekktor]&lt;br /&gt;
* ?Are there other alternatives?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! [[#Flowplayer_HTML5|Flowplayer HTML5]]&lt;br /&gt;
! [[#Video.JS|Video.JS]]&lt;br /&gt;
! [[#Projekktor|Projekktor]]&lt;br /&gt;
|-&lt;br /&gt;
! Accessible Player:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Keyboard control&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes (configurable)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Subtitles support&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via plugin)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Touch interface&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Appearance:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Skins&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* CSS customisation&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTL support&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
! Mobile platforms:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* iOS&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Android&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Streaming protocols:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTMP&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via playlist)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Adaptive HTTP&lt;br /&gt;
| HLS&lt;br /&gt;
| HLS (via plugin)&lt;br /&gt;
| HLS (via playlist)&lt;br /&gt;
|-&lt;br /&gt;
! Audio player&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Embedding support&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (configurable)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via addThis plugin)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via plugin)&lt;br /&gt;
|-&lt;br /&gt;
! License&lt;br /&gt;
| GPL v3 (with additional terms)&lt;br /&gt;
| Apache 2&lt;br /&gt;
| GPL v3&lt;br /&gt;
|-&lt;br /&gt;
! JS library&lt;br /&gt;
| jQuery&lt;br /&gt;
| -&lt;br /&gt;
| jQuery&lt;br /&gt;
|-&lt;br /&gt;
! Plugins infrastructure&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Flash fallback player&lt;br /&gt;
| Flowplayer Flash&lt;br /&gt;
| video-js flash&lt;br /&gt;
| StobeMediaPlayback (but can be jarisplayer or some other).&lt;br /&gt;
|-&lt;br /&gt;
! API&lt;br /&gt;
| Yes (plus window.flowplayer object)&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Flowplayer HTML5 ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* Good looking player, resembles existing flash flowplayer in Moodle (with &amp;quot;functional&amp;quot; skin)&lt;br /&gt;
* Extensive customisation (via CSS3 skins and configuration object)&lt;br /&gt;
* Streaming support (RTMP, HLS)&lt;br /&gt;
* Good accessibility features&lt;br /&gt;
* Configurable embedding functionality&lt;br /&gt;
* Existing flash flowplayer can be configured for fallback (the appearance of player will not be affected).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Require jQuery for functioning&lt;br /&gt;
* Flowplayer logo remains on screen&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using wrapper around &amp;lt;video&amp;gt;.&lt;br /&gt;
* width and height attributes in video tag are ignored, player size is configured via wrapper size only.&lt;br /&gt;
* RTMP server connection is configured via data-rtmp attribute in wrapper or player init config parameter, actual path the file specified in src attribute of source item.&lt;br /&gt;
* &amp;lt;source type=&amp;quot;video/flash&amp;quot;... dummy MIME type to force using plash player for whatever content.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Plugins infrastructure&lt;br /&gt;
* No audio support&lt;br /&gt;
&lt;br /&gt;
=== Video.JS ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Extensive API.&lt;br /&gt;
* No extra JS library needed.&lt;br /&gt;
* Many plugins.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Poor documentation&lt;br /&gt;
* RTMP requires non-standard MIME.&lt;br /&gt;
* Android and iOS override Video.JS with own player, when not overridden, content is not playing.&lt;br /&gt;
* No RTL.&lt;br /&gt;
* HLS support via plugin (many files to include, external contributor see https://github.com/videojs/videojs-contrib-hls).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* RTMP server connection and path specified as single URI in src attribute of source item, &#039;&amp;amp;&#039; character is used as server connection and path divider.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Embedded HLS support.&lt;br /&gt;
&lt;br /&gt;
=== Projekktor ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Well documented API.&lt;br /&gt;
* Media RSS support.&lt;br /&gt;
* Possibility to choose flash player for fallback (included by default are StrobeMediaPlayback and Jarisplayer, both Open Source).&lt;br /&gt;
* Platform preference order selection (e.g. browser, ios, android, flash, native).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Uses flash where it is not supposed to (e.g. mp4 in Chrome).&lt;br /&gt;
* Issues on ios and android (suggests to download file when play button is pressed).&lt;br /&gt;
* RTMP only work if defined via playlist rather than in &amp;lt;source&amp;gt; tags.&lt;br /&gt;
* Subtitles plugin is not free.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* Make sure &amp;lt;video&amp;gt; tag has class attribute with &#039;projekktor&#039; value (even if you initialise it by ID of the element), player will not work properly otherwise.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Cross-browser support ==&lt;br /&gt;
&lt;br /&gt;
=== Method ===&lt;br /&gt;
Compatibility checks were done manually by accessing the sample page using different browsers and platforms. Sample page contained the list of identical player instances, initialised for each &amp;lt;video&amp;gt; definition with a &amp;lt;source&amp;gt; of particular format: mp4, webm, ogg, flv. Streaming support was checked by setting up a &amp;lt;video&amp;gt; container with two sources of the same video, one was HLS (Apple HTTP Live Streaming) stream for browsers and platforms that support html5 video streaming, another one was RTMP which is played using flash engine and supposed to be used in case if HLS is not supported.&lt;br /&gt;
&lt;br /&gt;
=== Sample Pages ===&lt;br /&gt;
&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=flowplayer Flowplayer HTML5] version 5.4.6.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=videojs Video.JS] version 4.4.1.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=projekktor Projekktor] version 1.3.09.&lt;br /&gt;
&lt;br /&gt;
=== Source ===&lt;br /&gt;
&lt;br /&gt;
Source of testing page is hosted on [https://github.com/kabalin/test-html5-players/blob/master/players.php github]. The actual source of the html page can be viewed in browser.&lt;br /&gt;
&lt;br /&gt;
=== Discussion ===&lt;br /&gt;
&lt;br /&gt;
The players comparison that has been carried out demonstrated that &amp;quot;least hassle&amp;quot; player is Flowplayer. Despite some drawbacks listed in [[#Flowplayer_HTML5|corresponding section above]], it is clearly a winner as it works as expected and according to documentation for all browsers and platforms I had chance to test it. This is the only player that supports RTL layout, display platform incompatibility message prior to attempt to play, and was simple to configure (no undocumented tricks that I had to figure out to make it work). Both VideoJS and Projekktor do now perform properly in all cases. Among those two, I personally prefer Projekktor more for its extensive API, plugins infrastructure and configuration flexibility. However problems on mobile platforms and flash fallback inconsistency make them unreliable at this stage.&lt;br /&gt;
&lt;br /&gt;
=== Compatibility results ===&lt;br /&gt;
&lt;br /&gt;
The table was populated using Flowplayer as others do not perform good enough with some formats and platforms, e.g. VideoJS allow mobile platform player to override itself, Projekktor does not always use HTML5 where browser clearly can handle it (supported in native mode and Flowplayer).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Browser&lt;br /&gt;
! mp4&lt;br /&gt;
! webm&lt;br /&gt;
! ogg&lt;br /&gt;
! flv&lt;br /&gt;
! RTMP/HLS*&lt;br /&gt;
|-&lt;br /&gt;
! Windows 7&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Firefox 27.0.1&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 12.16&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 5.1.7&lt;br /&gt;
| flash&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Internet Explorer 11.0.9600.x&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Linux (Debian Wheezy)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.115&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! OSX 10.9&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 7.0 (9537.71)&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 phone (CyanogenMod, no flash)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 tablet (GalaxyTab2, flash app 11.1.115.36)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 19.0.1340.x&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
! iPhone 4S (6.1.3)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! iPad 4 (7.0.6)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;small&amp;gt;* For HLS/RTMP, html5 in the table means HLS has been used, flash means player fell back and used RTMP.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sub Tasks ==&lt;br /&gt;
&lt;br /&gt;
In initial stage FlowPlayer HTML5 (or any other) will handle all existing HTML5 Video extensions as per core_media_player_html5video class, plus m3u8 (HLS). It will also be possible optionally to make flash files handled by HTML5 Video player as well (possibility of using existing flash FlowPlayer for flv files will remain).&lt;br /&gt;
&lt;br /&gt;
== Mock-Ups/Prototypes ==&lt;br /&gt;
&lt;br /&gt;
See [[#Sample_Pages|Sample pages]] section.&lt;br /&gt;
&lt;br /&gt;
== Related Tracker Issues ==&lt;br /&gt;
* MDL-38158&lt;br /&gt;
&lt;br /&gt;
== Useful links ==&lt;br /&gt;
* http://praegnanz.de/html5video/&lt;br /&gt;
* http://html5video.org/wiki/HTML5_Video_Player_Comparison&lt;br /&gt;
* http://www.streamingmedia.com/Articles/Editorial/Featured-Articles/Choosing-a-Video-Player-Features-and-Specs-for-the-Top-Five-94188.aspx&lt;br /&gt;
&lt;br /&gt;
[[Category:Project]]&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=44143</id>
		<title>HTML5 player</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=44143"/>
		<updated>2014-03-10T15:45:36Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}&lt;br /&gt;
{{Infobox Project&lt;br /&gt;
|name = HTML5 Player with flash fallback&lt;br /&gt;
|state = In Development&lt;br /&gt;
|tracker = https://tracker.moodle.org/browse/MDL-38158&lt;br /&gt;
|discussion = https://moodle.org/mod/forum/discuss.php?d=222753#p1110024&lt;br /&gt;
|assignee = [https://tracker.moodle.org/secure/ViewProfile.jspa?name=kabalin Ruslan Kabalin]&lt;br /&gt;
}}&lt;br /&gt;
{{Moodle 2.x}}&lt;br /&gt;
&lt;br /&gt;
== Project goals ==&lt;br /&gt;
&lt;br /&gt;
The purpose of this document is to choose HTML5 with flash fallback for integration in Moodle.&lt;br /&gt;
&lt;br /&gt;
The aim of this change is to reach a consistent look of the player among different platforms and browsers, as well as making sure that player starts using flash if html5 is not supported by browser for the given format. Another aim is to improve accessibility and usability, enhance customisation.&lt;br /&gt;
&lt;br /&gt;
== Considerations ==&lt;br /&gt;
&lt;br /&gt;
* Usability of the player - is it easy to use it and intuitively understand how to use controls?&lt;br /&gt;
* Accessibility of the player - possibility of keyboard navigation, subtitles, support?&lt;br /&gt;
* Appearance of the player - can its interface be modified, themes support, RTL?&lt;br /&gt;
* Consistency among browsers - does player look the same?&lt;br /&gt;
* Audio support - can player handle HTML5 &amp;lt;audio&amp;gt; tag?&lt;br /&gt;
* Mobile platforms support - does player also work on iOS and Android?&lt;br /&gt;
* Streaming media support (including adaptive-bitrate delivery) - can player handle RTMP, Apple HLS, Adobe HDS, Microsoft HSS?&lt;br /&gt;
* Plugins support - can we use or develop community plugins easily?&lt;br /&gt;
* Embedding support - so users could post media content outside Moodle, if permitted.&lt;br /&gt;
* Maintainability of the links between the player and Moodle - how much work will we need to do every time we upgrade?&lt;br /&gt;
&lt;br /&gt;
== Candidates ==&lt;br /&gt;
&lt;br /&gt;
* [http://flowplayer.org/ Flowplayer HTML5]&lt;br /&gt;
* [http://www.videojs.com/ Video.JS]&lt;br /&gt;
* [http://www.projekktor.com/ Projekktor]&lt;br /&gt;
* ?Are there other alternatives?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! [[#Flowplayer_HTML5|Flowplayer HTML5]]&lt;br /&gt;
! [[#Video.JS|Video.JS]]&lt;br /&gt;
! [[#Projekktor|Projekktor]]&lt;br /&gt;
|-&lt;br /&gt;
! Accessible Player:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Keyboard control&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes (configurable)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Subtitles support&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via plugin)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Touch interface&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Appearance:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Skins&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* CSS customisation&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTL support&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
! Mobile platforms:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* iOS&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Android&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Streaming protocols:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTMP&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via playlist)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Adaptive HTTP&lt;br /&gt;
| HLS&lt;br /&gt;
| HLS (via plugin)&lt;br /&gt;
| HLS (via playlist)&lt;br /&gt;
|-&lt;br /&gt;
! Audio player&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Embedding support&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (configurable)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via addThis plugin)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via plugin)&lt;br /&gt;
|-&lt;br /&gt;
! License&lt;br /&gt;
| GPL v3 (with additional terms)&lt;br /&gt;
| Apache 2&lt;br /&gt;
| GPL v3&lt;br /&gt;
|-&lt;br /&gt;
! JS library&lt;br /&gt;
| jQuery&lt;br /&gt;
| -&lt;br /&gt;
| jQuery&lt;br /&gt;
|-&lt;br /&gt;
! Plugins infrastructure&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Flash fallback player&lt;br /&gt;
| Flowplayer Flash&lt;br /&gt;
| video-js flash&lt;br /&gt;
| StobeMediaPlayback (but can be jarisplayer or some other).&lt;br /&gt;
|-&lt;br /&gt;
! API&lt;br /&gt;
| Yes (plus window.flowplayer object)&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Flowplayer HTML5 ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* Good looking player, resembles existing flash flowplayer in Moodle (with &amp;quot;functional&amp;quot; skin)&lt;br /&gt;
* Extensive customisation (via CSS3 skins and configuration object)&lt;br /&gt;
* Streaming support (RTMP, HLS)&lt;br /&gt;
* Good accessibility features&lt;br /&gt;
* Configurable embedding functionality&lt;br /&gt;
* Existing flash flowplayer can be configured for fallback (the appearance of player will not be affected).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Require jQuery for functioning&lt;br /&gt;
* Flowplayer logo remains on screen&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using wrapper around &amp;lt;video&amp;gt;.&lt;br /&gt;
* width and height attributes in video tag are ignored, player size is configured via wrapper size only.&lt;br /&gt;
* RTMP server connection is configured via data-rtmp attribute in wrapper or player init config parameter, actual path the file specified in src attribute of source item.&lt;br /&gt;
* &amp;lt;source type=&amp;quot;video/flash&amp;quot;... dummy MIME type to force using plash player for whatever content.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Plugins infrastructure&lt;br /&gt;
* No audio support&lt;br /&gt;
&lt;br /&gt;
=== Video.JS ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Extensive API.&lt;br /&gt;
* No extra JS library needed.&lt;br /&gt;
* Many plugins.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Poor documentation&lt;br /&gt;
* RTMP requires non-standard MIME.&lt;br /&gt;
* Android and iOS override Video.JS with own player, when not overridden, content is not playing.&lt;br /&gt;
* No RTL.&lt;br /&gt;
* HLS support via plugin (many files to include, external contributor see https://github.com/videojs/videojs-contrib-hls).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* RTMP server connection and path specified as single URI in src attribute of source item, &#039;&amp;amp;&#039; character is used as server connection and path divider.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Embedded HLS support.&lt;br /&gt;
&lt;br /&gt;
=== Projekktor ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Well documented API.&lt;br /&gt;
* Media RSS support.&lt;br /&gt;
* Possibility to choose flash player for fallback (included by default are StrobeMediaPlayback and Jarisplayer, both Open Source).&lt;br /&gt;
* Platform preference order selection (e.g. browser, ios, android, flash, native).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Uses flash where it is not supposed to (e.g. mp4 in Chrome).&lt;br /&gt;
* Issues on ios and android (suggests to download file when play button is pressed).&lt;br /&gt;
* RTMP only work if defined via playlist rather than in &amp;lt;source&amp;gt; tags.&lt;br /&gt;
* Subtitles plugin is not free.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* Make sure &amp;lt;video&amp;gt; tag has class attribute with &#039;projekktor&#039; value (even if you initialise it by ID of the element), player will not work properly otherwise.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Cross-browser support ==&lt;br /&gt;
&lt;br /&gt;
=== Method ===&lt;br /&gt;
Compatibility checks were done manually by accessing the sample page using different browsers and platforms. Sample page contained the list of identical player instances, initialised for each &amp;lt;video&amp;gt; definition with a &amp;lt;source&amp;gt; of particular format: mp4, webm, ogg, flv. Streaming support was checked by setting up a &amp;lt;video&amp;gt; container with two sources of the same video, one was HLS (Apple HTTP Live Streaming) stream for browsers and platforms that support html5 video streaming, another one was RTMP which is played using flash engine and supposed to be used in case if HLS is not supported.&lt;br /&gt;
&lt;br /&gt;
=== Sample Pages ===&lt;br /&gt;
&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=flowplayer Flowplayer HTML5] version 5.4.6.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=videojs Video.JS] version 4.4.1.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=projekktor Projekktor] version 1.3.09.&lt;br /&gt;
&lt;br /&gt;
=== Source ===&lt;br /&gt;
&lt;br /&gt;
Source of testing page is hosted on [https://github.com/kabalin/test-html5-players/blob/master/players.php github]. The actual source of the html page can be viewed in browser.&lt;br /&gt;
&lt;br /&gt;
=== Discussion ===&lt;br /&gt;
&lt;br /&gt;
The players comparison that has been carried out demonstrated that &amp;quot;least hassle&amp;quot; player is Flowplayer. Despite some drawbacks listed in [[#Flowplayer_HTML5|corresponding section above]], it is clearly a winner as it works as expected and according to documentation for all browsers and platforms I had chance to test it. This is the only player that supports RTL layout, display platform incompatibility message prior to attempt to play, and was simple to configure (no undocumented tricks that I had to figure out to make it work). Both VideoJS and Projekktor do now perform properly in all cases. Among those two, I personally prefer Projekktor more for its extensive API, plugins infrastructure and configuration flexibility. However problems on mobile platforms and flash fallback inconsistency make them unreliable at this stage.&lt;br /&gt;
&lt;br /&gt;
=== Compatibility results ===&lt;br /&gt;
&lt;br /&gt;
The table was populated using Flowplayer as others do not perform good enough with some formats and platforms, e.g. VideoJS allow mobile platform player to override itself, Projekktor does not always use HTML5 where browser clearly can handle it (supported in native mode and Flowplayer).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Browser&lt;br /&gt;
! mp4&lt;br /&gt;
! webm&lt;br /&gt;
! ogg&lt;br /&gt;
! flv&lt;br /&gt;
! RTMP/HLS*&lt;br /&gt;
|-&lt;br /&gt;
! Windows 7&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Firefox 27.0.1&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 12.16&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 5.1.7&lt;br /&gt;
| flash&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Internet Explorer 11.0.9600.x&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Linux (Debian Wheezy)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.115&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! OSX 10.9&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 7.0 (9537.71)&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 phone (CyanogenMod, no flash)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 tablet (GalaxyTab2, flash app 11.1.115.36)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 19.0.1340.x&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
! iPhone 4S (6.1.3)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! iPad 4 (7.0.6)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;small&amp;gt;* For HLS/RTMP, html5 in the table means HLS has been used, flash means player fell back and used RTMP.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sub Tasks ==&lt;br /&gt;
&lt;br /&gt;
In initial stage FlowPlayer HTML5 (or any other) will handle all existing HTML5 Video extensions as per core_media_player_html5video class, plus m3u8 (HLS). It will also be possible optionally to make flash files handled by HTML5 Video player as well (possibility of using existing flash FlowPlayer for flv files will remain).&lt;br /&gt;
&lt;br /&gt;
== Mock-Ups/Prototypes ==&lt;br /&gt;
&lt;br /&gt;
See [[#Sample_Pages|Sample pages]] section.&lt;br /&gt;
&lt;br /&gt;
== Related Tracker Issues ==&lt;br /&gt;
* MDL-38158&lt;br /&gt;
&lt;br /&gt;
== Useful links ==&lt;br /&gt;
* http://praegnanz.de/html5video/&lt;br /&gt;
* http://html5video.org/wiki/HTML5_Video_Player_Comparison&lt;br /&gt;
* http://www.streamingmedia.com/Articles/Editorial/Featured-Articles/Choosing-a-Video-Player-Features-and-Specs-for-the-Top-Five-94188.aspx&lt;br /&gt;
&lt;br /&gt;
[[Category:Project]]&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=44142</id>
		<title>HTML5 player</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=44142"/>
		<updated>2014-03-10T15:37:14Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: /* Sub Tasks */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}&lt;br /&gt;
{{Infobox Project&lt;br /&gt;
|name = HTML5 Player with flash fallback&lt;br /&gt;
|state = In Development&lt;br /&gt;
|tracker = https://tracker.moodle.org/browse/MDL-38158&lt;br /&gt;
|discussion = https://moodle.org/mod/forum/discuss.php?d=222753#p1105373&lt;br /&gt;
|assignee = [https://tracker.moodle.org/secure/ViewProfile.jspa?name=kabalin Ruslan Kabalin]&lt;br /&gt;
}}&lt;br /&gt;
{{Moodle 2.x}}&lt;br /&gt;
&lt;br /&gt;
== Project goals ==&lt;br /&gt;
&lt;br /&gt;
The purpose of this document is to choose HTML5 with flash fallback for integration in Moodle.&lt;br /&gt;
&lt;br /&gt;
The aim of this change is to reach a consistent look of the player among different platforms and browsers, as well as making sure that player starts using flash if html5 is not supported by browser for the given format. Another aim is to improve accessibility and usability, enhance customisation.&lt;br /&gt;
&lt;br /&gt;
== Considerations ==&lt;br /&gt;
&lt;br /&gt;
* Usability of the player - is it easy to use it and intuitively understand how to use controls?&lt;br /&gt;
* Accessibility of the player - possibility of keyboard navigation, subtitles, support?&lt;br /&gt;
* Appearance of the player - can its interface be modified, themes support, RTL?&lt;br /&gt;
* Consistency among browsers - does player look the same?&lt;br /&gt;
* Audio support - can player handle HTML5 &amp;lt;audio&amp;gt; tag?&lt;br /&gt;
* Mobile platforms support - does player also work on iOS and Android?&lt;br /&gt;
* Streaming media support (including adaptive-bitrate delivery) - can player handle RTMP, Apple HLS, Adobe HDS, Microsoft HSS?&lt;br /&gt;
* Plugins support - can we use or develop community plugins easily?&lt;br /&gt;
* Embedding support - so users could post media content outside Moodle, if permitted.&lt;br /&gt;
* Maintainability of the links between the player and Moodle - how much work will we need to do every time we upgrade?&lt;br /&gt;
&lt;br /&gt;
== Candidates ==&lt;br /&gt;
&lt;br /&gt;
* [http://flowplayer.org/ Flowplayer HTML5]&lt;br /&gt;
* [http://www.videojs.com/ Video.JS]&lt;br /&gt;
* [http://www.projekktor.com/ Projekktor]&lt;br /&gt;
* ?Are there other alternatives?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! [[#Flowplayer_HTML5|Flowplayer HTML5]]&lt;br /&gt;
! [[#Video.JS|Video.JS]]&lt;br /&gt;
! [[#Projekktor|Projekktor]]&lt;br /&gt;
|-&lt;br /&gt;
! Accessible Player:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Keyboard control&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes (configurable)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Subtitles support&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via plugin)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Touch interface&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Appearance:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Skins&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* CSS customisation&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTL support&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
! Mobile platforms:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* iOS&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Android&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Streaming protocols:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTMP&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via playlist)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Adaptive HTTP&lt;br /&gt;
| HLS&lt;br /&gt;
| HLS (via plugin)&lt;br /&gt;
| HLS (via playlist)&lt;br /&gt;
|-&lt;br /&gt;
! Audio player&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Embedding support&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (configurable)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via addThis plugin)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via plugin)&lt;br /&gt;
|-&lt;br /&gt;
! License&lt;br /&gt;
| GPL v3 (with additional terms)&lt;br /&gt;
| Apache 2&lt;br /&gt;
| GPL v3&lt;br /&gt;
|-&lt;br /&gt;
! JS library&lt;br /&gt;
| jQuery&lt;br /&gt;
| -&lt;br /&gt;
| jQuery&lt;br /&gt;
|-&lt;br /&gt;
! Plugins infrastructure&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Flash fallback player&lt;br /&gt;
| Flowplayer Flash&lt;br /&gt;
| video-js flash&lt;br /&gt;
| StobeMediaPlayback (but can be jarisplayer or some other).&lt;br /&gt;
|-&lt;br /&gt;
! API&lt;br /&gt;
| Yes (plus window.flowplayer object)&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Flowplayer HTML5 ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* Good looking player, resembles existing flash flowplayer in Moodle (with &amp;quot;functional&amp;quot; skin)&lt;br /&gt;
* Extensive customisation (via CSS3 skins and configuration object)&lt;br /&gt;
* Streaming support (RTMP, HLS)&lt;br /&gt;
* Good accessibility features&lt;br /&gt;
* Configurable embedding functionality&lt;br /&gt;
* Existing flash flowplayer can be configured for fallback (the appearance of player will not be affected).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Require jQuery for functioning&lt;br /&gt;
* Flowplayer logo remains on screen&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using wrapper around &amp;lt;video&amp;gt;.&lt;br /&gt;
* width and height attributes in video tag are ignored, player size is configured via wrapper size only.&lt;br /&gt;
* RTMP server connection is configured via data-rtmp attribute in wrapper or player init config parameter, actual path the file specified in src attribute of source item.&lt;br /&gt;
* &amp;lt;source type=&amp;quot;video/flash&amp;quot;... dummy MIME type to force using plash player for whatever content.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Plugins infrastructure&lt;br /&gt;
* No audio support&lt;br /&gt;
&lt;br /&gt;
=== Video.JS ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Extensive API.&lt;br /&gt;
* No extra JS library needed.&lt;br /&gt;
* Many plugins.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Poor documentation&lt;br /&gt;
* RTMP requires non-standard MIME.&lt;br /&gt;
* Android and iOS override Video.JS with own player, when not overridden, content is not playing.&lt;br /&gt;
* No RTL.&lt;br /&gt;
* HLS support via plugin (many files to include, external contributor see https://github.com/videojs/videojs-contrib-hls).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* RTMP server connection and path specified as single URI in src attribute of source item, &#039;&amp;amp;&#039; character is used as server connection and path divider.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Embedded HLS support.&lt;br /&gt;
&lt;br /&gt;
=== Projekktor ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Well documented API.&lt;br /&gt;
* Media RSS support.&lt;br /&gt;
* Possibility to choose flash player for fallback (included by default are StrobeMediaPlayback and Jarisplayer, both Open Source).&lt;br /&gt;
* Platform preference order selection (e.g. browser, ios, android, flash, native).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Uses flash where it is not supposed to (e.g. mp4 in Chrome).&lt;br /&gt;
* Issues on ios and android (suggests to download file when play button is pressed).&lt;br /&gt;
* RTMP only work if defined via playlist rather than in &amp;lt;source&amp;gt; tags.&lt;br /&gt;
* Subtitles plugin is not free.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* Make sure &amp;lt;video&amp;gt; tag has class attribute with &#039;projekktor&#039; value (even if you initialise it by ID of the element), player will not work properly otherwise.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Cross-browser support ==&lt;br /&gt;
&lt;br /&gt;
=== Method ===&lt;br /&gt;
Compatibility checks were done manually by accessing the sample page using different browsers and platforms. Sample page contained the list of identical player instances, initialised for each &amp;lt;video&amp;gt; definition with a &amp;lt;source&amp;gt; of particular format: mp4, webm, ogg, flv. Streaming support was checked by setting up a &amp;lt;video&amp;gt; container with two sources of the same video, one was HLS (Apple HTTP Live Streaming) stream for browsers and platforms that support html5 video streaming, another one was RTMP which is played using flash engine and supposed to be used in case if HLS is not supported.&lt;br /&gt;
&lt;br /&gt;
=== Sample Pages ===&lt;br /&gt;
&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=flowplayer Flowplayer HTML5] version 5.4.6.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=videojs Video.JS] version 4.4.1.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=projekktor Projekktor] version 1.3.09.&lt;br /&gt;
&lt;br /&gt;
=== Source ===&lt;br /&gt;
&lt;br /&gt;
Source of testing page is hosted on [https://github.com/kabalin/test-html5-players/blob/master/players.php github]. The actual source of the html page can be viewed in browser.&lt;br /&gt;
&lt;br /&gt;
=== Discussion ===&lt;br /&gt;
&lt;br /&gt;
The players comparison that has been carried out demonstrated that &amp;quot;least hassle&amp;quot; player is Flowplayer. Despite some drawbacks listed in [[#Flowplayer_HTML5|corresponding section above]], it is clearly a winner as it works as expected and according to documentation for all browsers and platforms I had chance to test it. This is the only player that supports RTL layout, display platform incompatibility message prior to attempt to play, and was simple to configure (no undocumented tricks that I had to figure out to make it work). Both VideoJS and Projekktor do now perform properly in all cases. Among those two, I personally prefer Projekktor more for its extensive API, plugins infrastructure and configuration flexibility. However problems on mobile platforms and flash fallback inconsistency make them unreliable at this stage.&lt;br /&gt;
&lt;br /&gt;
=== Compatibility results ===&lt;br /&gt;
&lt;br /&gt;
The table was populated using Flowplayer as others do not perform good enough with some formats and platforms, e.g. VideoJS allow mobile platform player to override itself, Projekktor does not always use HTML5 where browser clearly can handle it (supported in native mode and Flowplayer).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Browser&lt;br /&gt;
! mp4&lt;br /&gt;
! webm&lt;br /&gt;
! ogg&lt;br /&gt;
! flv&lt;br /&gt;
! RTMP/HLS*&lt;br /&gt;
|-&lt;br /&gt;
! Windows 7&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Firefox 27.0.1&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 12.16&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 5.1.7&lt;br /&gt;
| flash&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Internet Explorer 11.0.9600.x&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Linux (Debian Wheezy)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.115&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! OSX 10.9&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 7.0 (9537.71)&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 phone (CyanogenMod, no flash)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 tablet (GalaxyTab2, flash app 11.1.115.36)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 19.0.1340.x&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
! iPhone 4S (6.1.3)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! iPad 4 (7.0.6)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;small&amp;gt;* For HLS/RTMP, html5 in the table means HLS has been used, flash means player fell back and used RTMP.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sub Tasks ==&lt;br /&gt;
&lt;br /&gt;
In initial stage FlowPlayer HTML5 (or any other) will handle all existing HTML5 Video extensions as per core_media_player_html5video class, plus m3u8 (HLS). It will also be possible optionally to make flash files handled by HTML5 Video player as well (possibility of using existing flash FlowPlayer for flv files will remain).&lt;br /&gt;
&lt;br /&gt;
== Mock-Ups/Prototypes ==&lt;br /&gt;
&lt;br /&gt;
See [[#Sample_Pages|Sample pages]] section.&lt;br /&gt;
&lt;br /&gt;
== Related Tracker Issues ==&lt;br /&gt;
* MDL-38158&lt;br /&gt;
&lt;br /&gt;
== Useful links ==&lt;br /&gt;
* http://praegnanz.de/html5video/&lt;br /&gt;
* http://html5video.org/wiki/HTML5_Video_Player_Comparison&lt;br /&gt;
* http://www.streamingmedia.com/Articles/Editorial/Featured-Articles/Choosing-a-Video-Player-Features-and-Specs-for-the-Top-Five-94188.aspx&lt;br /&gt;
&lt;br /&gt;
[[Category:Project]]&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=44141</id>
		<title>HTML5 player</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=44141"/>
		<updated>2014-03-10T14:46:10Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: /* Candidates */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}&lt;br /&gt;
{{Infobox Project&lt;br /&gt;
|name = HTML5 Player with flash fallback&lt;br /&gt;
|state = In Development&lt;br /&gt;
|tracker = https://tracker.moodle.org/browse/MDL-38158&lt;br /&gt;
|discussion = https://moodle.org/mod/forum/discuss.php?d=222753#p1105373&lt;br /&gt;
|assignee = [https://tracker.moodle.org/secure/ViewProfile.jspa?name=kabalin Ruslan Kabalin]&lt;br /&gt;
}}&lt;br /&gt;
{{Moodle 2.x}}&lt;br /&gt;
&lt;br /&gt;
== Project goals ==&lt;br /&gt;
&lt;br /&gt;
The purpose of this document is to choose HTML5 with flash fallback for integration in Moodle.&lt;br /&gt;
&lt;br /&gt;
The aim of this change is to reach a consistent look of the player among different platforms and browsers, as well as making sure that player starts using flash if html5 is not supported by browser for the given format. Another aim is to improve accessibility and usability, enhance customisation.&lt;br /&gt;
&lt;br /&gt;
== Considerations ==&lt;br /&gt;
&lt;br /&gt;
* Usability of the player - is it easy to use it and intuitively understand how to use controls?&lt;br /&gt;
* Accessibility of the player - possibility of keyboard navigation, subtitles, support?&lt;br /&gt;
* Appearance of the player - can its interface be modified, themes support, RTL?&lt;br /&gt;
* Consistency among browsers - does player look the same?&lt;br /&gt;
* Audio support - can player handle HTML5 &amp;lt;audio&amp;gt; tag?&lt;br /&gt;
* Mobile platforms support - does player also work on iOS and Android?&lt;br /&gt;
* Streaming media support (including adaptive-bitrate delivery) - can player handle RTMP, Apple HLS, Adobe HDS, Microsoft HSS?&lt;br /&gt;
* Plugins support - can we use or develop community plugins easily?&lt;br /&gt;
* Embedding support - so users could post media content outside Moodle, if permitted.&lt;br /&gt;
* Maintainability of the links between the player and Moodle - how much work will we need to do every time we upgrade?&lt;br /&gt;
&lt;br /&gt;
== Candidates ==&lt;br /&gt;
&lt;br /&gt;
* [http://flowplayer.org/ Flowplayer HTML5]&lt;br /&gt;
* [http://www.videojs.com/ Video.JS]&lt;br /&gt;
* [http://www.projekktor.com/ Projekktor]&lt;br /&gt;
* ?Are there other alternatives?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! [[#Flowplayer_HTML5|Flowplayer HTML5]]&lt;br /&gt;
! [[#Video.JS|Video.JS]]&lt;br /&gt;
! [[#Projekktor|Projekktor]]&lt;br /&gt;
|-&lt;br /&gt;
! Accessible Player:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Keyboard control&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes (configurable)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Subtitles support&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via plugin)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Touch interface&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Appearance:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Skins&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* CSS customisation&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTL support&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
! Mobile platforms:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* iOS&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Android&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Streaming protocols:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTMP&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via playlist)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Adaptive HTTP&lt;br /&gt;
| HLS&lt;br /&gt;
| HLS (via plugin)&lt;br /&gt;
| HLS (via playlist)&lt;br /&gt;
|-&lt;br /&gt;
! Audio player&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Embedding support&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (configurable)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via addThis plugin)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via plugin)&lt;br /&gt;
|-&lt;br /&gt;
! License&lt;br /&gt;
| GPL v3 (with additional terms)&lt;br /&gt;
| Apache 2&lt;br /&gt;
| GPL v3&lt;br /&gt;
|-&lt;br /&gt;
! JS library&lt;br /&gt;
| jQuery&lt;br /&gt;
| -&lt;br /&gt;
| jQuery&lt;br /&gt;
|-&lt;br /&gt;
! Plugins infrastructure&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Flash fallback player&lt;br /&gt;
| Flowplayer Flash&lt;br /&gt;
| video-js flash&lt;br /&gt;
| StobeMediaPlayback (but can be jarisplayer or some other).&lt;br /&gt;
|-&lt;br /&gt;
! API&lt;br /&gt;
| Yes (plus window.flowplayer object)&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Flowplayer HTML5 ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* Good looking player, resembles existing flash flowplayer in Moodle (with &amp;quot;functional&amp;quot; skin)&lt;br /&gt;
* Extensive customisation (via CSS3 skins and configuration object)&lt;br /&gt;
* Streaming support (RTMP, HLS)&lt;br /&gt;
* Good accessibility features&lt;br /&gt;
* Configurable embedding functionality&lt;br /&gt;
* Existing flash flowplayer can be configured for fallback (the appearance of player will not be affected).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Require jQuery for functioning&lt;br /&gt;
* Flowplayer logo remains on screen&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using wrapper around &amp;lt;video&amp;gt;.&lt;br /&gt;
* width and height attributes in video tag are ignored, player size is configured via wrapper size only.&lt;br /&gt;
* RTMP server connection is configured via data-rtmp attribute in wrapper or player init config parameter, actual path the file specified in src attribute of source item.&lt;br /&gt;
* &amp;lt;source type=&amp;quot;video/flash&amp;quot;... dummy MIME type to force using plash player for whatever content.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Plugins infrastructure&lt;br /&gt;
* No audio support&lt;br /&gt;
&lt;br /&gt;
=== Video.JS ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Extensive API.&lt;br /&gt;
* No extra JS library needed.&lt;br /&gt;
* Many plugins.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Poor documentation&lt;br /&gt;
* RTMP requires non-standard MIME.&lt;br /&gt;
* Android and iOS override Video.JS with own player, when not overridden, content is not playing.&lt;br /&gt;
* No RTL.&lt;br /&gt;
* HLS support via plugin (many files to include, external contributor see https://github.com/videojs/videojs-contrib-hls).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* RTMP server connection and path specified as single URI in src attribute of source item, &#039;&amp;amp;&#039; character is used as server connection and path divider.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Embedded HLS support.&lt;br /&gt;
&lt;br /&gt;
=== Projekktor ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Well documented API.&lt;br /&gt;
* Media RSS support.&lt;br /&gt;
* Possibility to choose flash player for fallback (included by default are StrobeMediaPlayback and Jarisplayer, both Open Source).&lt;br /&gt;
* Platform preference order selection (e.g. browser, ios, android, flash, native).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Uses flash where it is not supposed to (e.g. mp4 in Chrome).&lt;br /&gt;
* Issues on ios and android (suggests to download file when play button is pressed).&lt;br /&gt;
* RTMP only work if defined via playlist rather than in &amp;lt;source&amp;gt; tags.&lt;br /&gt;
* Subtitles plugin is not free.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* Make sure &amp;lt;video&amp;gt; tag has class attribute with &#039;projekktor&#039; value (even if you initialise it by ID of the element), player will not work properly otherwise.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Cross-browser support ==&lt;br /&gt;
&lt;br /&gt;
=== Method ===&lt;br /&gt;
Compatibility checks were done manually by accessing the sample page using different browsers and platforms. Sample page contained the list of identical player instances, initialised for each &amp;lt;video&amp;gt; definition with a &amp;lt;source&amp;gt; of particular format: mp4, webm, ogg, flv. Streaming support was checked by setting up a &amp;lt;video&amp;gt; container with two sources of the same video, one was HLS (Apple HTTP Live Streaming) stream for browsers and platforms that support html5 video streaming, another one was RTMP which is played using flash engine and supposed to be used in case if HLS is not supported.&lt;br /&gt;
&lt;br /&gt;
=== Sample Pages ===&lt;br /&gt;
&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=flowplayer Flowplayer HTML5] version 5.4.6.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=videojs Video.JS] version 4.4.1.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=projekktor Projekktor] version 1.3.09.&lt;br /&gt;
&lt;br /&gt;
=== Source ===&lt;br /&gt;
&lt;br /&gt;
Source of testing page is hosted on [https://github.com/kabalin/test-html5-players/blob/master/players.php github]. The actual source of the html page can be viewed in browser.&lt;br /&gt;
&lt;br /&gt;
=== Discussion ===&lt;br /&gt;
&lt;br /&gt;
The players comparison that has been carried out demonstrated that &amp;quot;least hassle&amp;quot; player is Flowplayer. Despite some drawbacks listed in [[#Flowplayer_HTML5|corresponding section above]], it is clearly a winner as it works as expected and according to documentation for all browsers and platforms I had chance to test it. This is the only player that supports RTL layout, display platform incompatibility message prior to attempt to play, and was simple to configure (no undocumented tricks that I had to figure out to make it work). Both VideoJS and Projekktor do now perform properly in all cases. Among those two, I personally prefer Projekktor more for its extensive API, plugins infrastructure and configuration flexibility. However problems on mobile platforms and flash fallback inconsistency make them unreliable at this stage.&lt;br /&gt;
&lt;br /&gt;
=== Compatibility results ===&lt;br /&gt;
&lt;br /&gt;
The table was populated using Flowplayer as others do not perform good enough with some formats and platforms, e.g. VideoJS allow mobile platform player to override itself, Projekktor does not always use HTML5 where browser clearly can handle it (supported in native mode and Flowplayer).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Browser&lt;br /&gt;
! mp4&lt;br /&gt;
! webm&lt;br /&gt;
! ogg&lt;br /&gt;
! flv&lt;br /&gt;
! RTMP/HLS*&lt;br /&gt;
|-&lt;br /&gt;
! Windows 7&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Firefox 27.0.1&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 12.16&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 5.1.7&lt;br /&gt;
| flash&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Internet Explorer 11.0.9600.x&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Linux (Debian Wheezy)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.115&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! OSX 10.9&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 7.0 (9537.71)&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 phone (CyanogenMod, no flash)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 tablet (GalaxyTab2, flash app 11.1.115.36)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 19.0.1340.x&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
! iPhone 4S (6.1.3)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! iPad 4 (7.0.6)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;small&amp;gt;* For HLS/RTMP, html5 in the table means HLS has been used, flash means player fell back and used RTMP.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sub Tasks ==&lt;br /&gt;
&lt;br /&gt;
== Mock-Ups/Prototypes ==&lt;br /&gt;
&lt;br /&gt;
See [[#Sample_Pages|Sample pages]] section.&lt;br /&gt;
&lt;br /&gt;
== Related Tracker Issues ==&lt;br /&gt;
* MDL-38158&lt;br /&gt;
&lt;br /&gt;
== Useful links ==&lt;br /&gt;
* http://praegnanz.de/html5video/&lt;br /&gt;
* http://html5video.org/wiki/HTML5_Video_Player_Comparison&lt;br /&gt;
* http://www.streamingmedia.com/Articles/Editorial/Featured-Articles/Choosing-a-Video-Player-Features-and-Specs-for-the-Top-Five-94188.aspx&lt;br /&gt;
&lt;br /&gt;
[[Category:Project]]&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=44140</id>
		<title>HTML5 player</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=44140"/>
		<updated>2014-03-10T14:44:54Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: /* Video.JS */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}&lt;br /&gt;
{{Infobox Project&lt;br /&gt;
|name = HTML5 Player with flash fallback&lt;br /&gt;
|state = In Development&lt;br /&gt;
|tracker = https://tracker.moodle.org/browse/MDL-38158&lt;br /&gt;
|discussion = https://moodle.org/mod/forum/discuss.php?d=222753#p1105373&lt;br /&gt;
|assignee = [https://tracker.moodle.org/secure/ViewProfile.jspa?name=kabalin Ruslan Kabalin]&lt;br /&gt;
}}&lt;br /&gt;
{{Moodle 2.x}}&lt;br /&gt;
&lt;br /&gt;
== Project goals ==&lt;br /&gt;
&lt;br /&gt;
The purpose of this document is to choose HTML5 with flash fallback for integration in Moodle.&lt;br /&gt;
&lt;br /&gt;
The aim of this change is to reach a consistent look of the player among different platforms and browsers, as well as making sure that player starts using flash if html5 is not supported by browser for the given format. Another aim is to improve accessibility and usability, enhance customisation.&lt;br /&gt;
&lt;br /&gt;
== Considerations ==&lt;br /&gt;
&lt;br /&gt;
* Usability of the player - is it easy to use it and intuitively understand how to use controls?&lt;br /&gt;
* Accessibility of the player - possibility of keyboard navigation, subtitles, support?&lt;br /&gt;
* Appearance of the player - can its interface be modified, themes support, RTL?&lt;br /&gt;
* Consistency among browsers - does player look the same?&lt;br /&gt;
* Audio support - can player handle HTML5 &amp;lt;audio&amp;gt; tag?&lt;br /&gt;
* Mobile platforms support - does player also work on iOS and Android?&lt;br /&gt;
* Streaming media support (including adaptive-bitrate delivery) - can player handle RTMP, Apple HLS, Adobe HDS, Microsoft HSS?&lt;br /&gt;
* Plugins support - can we use or develop community plugins easily?&lt;br /&gt;
* Embedding support - so users could post media content outside Moodle, if permitted.&lt;br /&gt;
* Maintainability of the links between the player and Moodle - how much work will we need to do every time we upgrade?&lt;br /&gt;
&lt;br /&gt;
== Candidates ==&lt;br /&gt;
&lt;br /&gt;
* [http://flowplayer.org/ Flowplayer HTML5]&lt;br /&gt;
* [http://www.videojs.com/ Video.JS]&lt;br /&gt;
* [http://www.projekktor.com/ Projekktor]&lt;br /&gt;
* ?Are there other alternatives?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Flowplayer HTML5&lt;br /&gt;
! Video.JS&lt;br /&gt;
! Projekktor&lt;br /&gt;
|-&lt;br /&gt;
! Accessible Player:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Keyboard control&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes (configurable)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Subtitles support&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via plugin)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Touch interface&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Appearance:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Skins&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* CSS customisation&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTL support&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
! Mobile platforms:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* iOS&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Android&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Streaming protocols:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTMP&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via playlist)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Adaptive HTTP&lt;br /&gt;
| HLS&lt;br /&gt;
| HLS (via plugin)&lt;br /&gt;
| HLS (via playlist)&lt;br /&gt;
|-&lt;br /&gt;
! Audio player&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Embedding support&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (configurable)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via addThis plugin)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via plugin)&lt;br /&gt;
|-&lt;br /&gt;
! License&lt;br /&gt;
| GPL v3 (with additional terms)&lt;br /&gt;
| Apache 2&lt;br /&gt;
| GPL v3&lt;br /&gt;
|-&lt;br /&gt;
! JS library&lt;br /&gt;
| jQuery&lt;br /&gt;
| -&lt;br /&gt;
| jQuery&lt;br /&gt;
|-&lt;br /&gt;
! Plugins infrastructure&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Flash fallback player&lt;br /&gt;
| Flowplayer Flash&lt;br /&gt;
| video-js flash&lt;br /&gt;
| StobeMediaPlayback (but can be jarisplayer or some other).&lt;br /&gt;
|-&lt;br /&gt;
! API&lt;br /&gt;
| Yes (plus window.flowplayer object)&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Flowplayer HTML5 ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* Good looking player, resembles existing flash flowplayer in Moodle (with &amp;quot;functional&amp;quot; skin)&lt;br /&gt;
* Extensive customisation (via CSS3 skins and configuration object)&lt;br /&gt;
* Streaming support (RTMP, HLS)&lt;br /&gt;
* Good accessibility features&lt;br /&gt;
* Configurable embedding functionality&lt;br /&gt;
* Existing flash flowplayer can be configured for fallback (the appearance of player will not be affected).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Require jQuery for functioning&lt;br /&gt;
* Flowplayer logo remains on screen&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using wrapper around &amp;lt;video&amp;gt;.&lt;br /&gt;
* width and height attributes in video tag are ignored, player size is configured via wrapper size only.&lt;br /&gt;
* RTMP server connection is configured via data-rtmp attribute in wrapper or player init config parameter, actual path the file specified in src attribute of source item.&lt;br /&gt;
* &amp;lt;source type=&amp;quot;video/flash&amp;quot;... dummy MIME type to force using plash player for whatever content.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Plugins infrastructure&lt;br /&gt;
* No audio support&lt;br /&gt;
&lt;br /&gt;
=== Video.JS ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Extensive API.&lt;br /&gt;
* No extra JS library needed.&lt;br /&gt;
* Many plugins.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Poor documentation&lt;br /&gt;
* RTMP requires non-standard MIME.&lt;br /&gt;
* Android and iOS override Video.JS with own player, when not overridden, content is not playing.&lt;br /&gt;
* No RTL.&lt;br /&gt;
* HLS support via plugin (many files to include, external contributor see https://github.com/videojs/videojs-contrib-hls).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* RTMP server connection and path specified as single URI in src attribute of source item, &#039;&amp;amp;&#039; character is used as server connection and path divider.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Embedded HLS support.&lt;br /&gt;
&lt;br /&gt;
=== Projekktor ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Well documented API.&lt;br /&gt;
* Media RSS support.&lt;br /&gt;
* Possibility to choose flash player for fallback (included by default are StrobeMediaPlayback and Jarisplayer, both Open Source).&lt;br /&gt;
* Platform preference order selection (e.g. browser, ios, android, flash, native).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Uses flash where it is not supposed to (e.g. mp4 in Chrome).&lt;br /&gt;
* Issues on ios and android (suggests to download file when play button is pressed).&lt;br /&gt;
* RTMP only work if defined via playlist rather than in &amp;lt;source&amp;gt; tags.&lt;br /&gt;
* Subtitles plugin is not free.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* Make sure &amp;lt;video&amp;gt; tag has class attribute with &#039;projekktor&#039; value (even if you initialise it by ID of the element), player will not work properly otherwise.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Cross-browser support ==&lt;br /&gt;
&lt;br /&gt;
=== Method ===&lt;br /&gt;
Compatibility checks were done manually by accessing the sample page using different browsers and platforms. Sample page contained the list of identical player instances, initialised for each &amp;lt;video&amp;gt; definition with a &amp;lt;source&amp;gt; of particular format: mp4, webm, ogg, flv. Streaming support was checked by setting up a &amp;lt;video&amp;gt; container with two sources of the same video, one was HLS (Apple HTTP Live Streaming) stream for browsers and platforms that support html5 video streaming, another one was RTMP which is played using flash engine and supposed to be used in case if HLS is not supported.&lt;br /&gt;
&lt;br /&gt;
=== Sample Pages ===&lt;br /&gt;
&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=flowplayer Flowplayer HTML5] version 5.4.6.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=videojs Video.JS] version 4.4.1.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=projekktor Projekktor] version 1.3.09.&lt;br /&gt;
&lt;br /&gt;
=== Source ===&lt;br /&gt;
&lt;br /&gt;
Source of testing page is hosted on [https://github.com/kabalin/test-html5-players/blob/master/players.php github]. The actual source of the html page can be viewed in browser.&lt;br /&gt;
&lt;br /&gt;
=== Discussion ===&lt;br /&gt;
&lt;br /&gt;
The players comparison that has been carried out demonstrated that &amp;quot;least hassle&amp;quot; player is Flowplayer. Despite some drawbacks listed in [[#Flowplayer_HTML5|corresponding section above]], it is clearly a winner as it works as expected and according to documentation for all browsers and platforms I had chance to test it. This is the only player that supports RTL layout, display platform incompatibility message prior to attempt to play, and was simple to configure (no undocumented tricks that I had to figure out to make it work). Both VideoJS and Projekktor do now perform properly in all cases. Among those two, I personally prefer Projekktor more for its extensive API, plugins infrastructure and configuration flexibility. However problems on mobile platforms and flash fallback inconsistency make them unreliable at this stage.&lt;br /&gt;
&lt;br /&gt;
=== Compatibility results ===&lt;br /&gt;
&lt;br /&gt;
The table was populated using Flowplayer as others do not perform good enough with some formats and platforms, e.g. VideoJS allow mobile platform player to override itself, Projekktor does not always use HTML5 where browser clearly can handle it (supported in native mode and Flowplayer).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Browser&lt;br /&gt;
! mp4&lt;br /&gt;
! webm&lt;br /&gt;
! ogg&lt;br /&gt;
! flv&lt;br /&gt;
! RTMP/HLS*&lt;br /&gt;
|-&lt;br /&gt;
! Windows 7&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Firefox 27.0.1&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 12.16&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 5.1.7&lt;br /&gt;
| flash&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Internet Explorer 11.0.9600.x&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Linux (Debian Wheezy)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.115&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! OSX 10.9&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 7.0 (9537.71)&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 phone (CyanogenMod, no flash)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 tablet (GalaxyTab2, flash app 11.1.115.36)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 19.0.1340.x&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
! iPhone 4S (6.1.3)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! iPad 4 (7.0.6)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;small&amp;gt;* For HLS/RTMP, html5 in the table means HLS has been used, flash means player fell back and used RTMP.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sub Tasks ==&lt;br /&gt;
&lt;br /&gt;
== Mock-Ups/Prototypes ==&lt;br /&gt;
&lt;br /&gt;
See [[#Sample_Pages|Sample pages]] section.&lt;br /&gt;
&lt;br /&gt;
== Related Tracker Issues ==&lt;br /&gt;
* MDL-38158&lt;br /&gt;
&lt;br /&gt;
== Useful links ==&lt;br /&gt;
* http://praegnanz.de/html5video/&lt;br /&gt;
* http://html5video.org/wiki/HTML5_Video_Player_Comparison&lt;br /&gt;
* http://www.streamingmedia.com/Articles/Editorial/Featured-Articles/Choosing-a-Video-Player-Features-and-Specs-for-the-Top-Five-94188.aspx&lt;br /&gt;
&lt;br /&gt;
[[Category:Project]]&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=44139</id>
		<title>HTML5 player</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=44139"/>
		<updated>2014-03-10T14:44:16Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: /* Mock-Ups/Prototypes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}&lt;br /&gt;
{{Infobox Project&lt;br /&gt;
|name = HTML5 Player with flash fallback&lt;br /&gt;
|state = In Development&lt;br /&gt;
|tracker = https://tracker.moodle.org/browse/MDL-38158&lt;br /&gt;
|discussion = https://moodle.org/mod/forum/discuss.php?d=222753#p1105373&lt;br /&gt;
|assignee = [https://tracker.moodle.org/secure/ViewProfile.jspa?name=kabalin Ruslan Kabalin]&lt;br /&gt;
}}&lt;br /&gt;
{{Moodle 2.x}}&lt;br /&gt;
&lt;br /&gt;
== Project goals ==&lt;br /&gt;
&lt;br /&gt;
The purpose of this document is to choose HTML5 with flash fallback for integration in Moodle.&lt;br /&gt;
&lt;br /&gt;
The aim of this change is to reach a consistent look of the player among different platforms and browsers, as well as making sure that player starts using flash if html5 is not supported by browser for the given format. Another aim is to improve accessibility and usability, enhance customisation.&lt;br /&gt;
&lt;br /&gt;
== Considerations ==&lt;br /&gt;
&lt;br /&gt;
* Usability of the player - is it easy to use it and intuitively understand how to use controls?&lt;br /&gt;
* Accessibility of the player - possibility of keyboard navigation, subtitles, support?&lt;br /&gt;
* Appearance of the player - can its interface be modified, themes support, RTL?&lt;br /&gt;
* Consistency among browsers - does player look the same?&lt;br /&gt;
* Audio support - can player handle HTML5 &amp;lt;audio&amp;gt; tag?&lt;br /&gt;
* Mobile platforms support - does player also work on iOS and Android?&lt;br /&gt;
* Streaming media support (including adaptive-bitrate delivery) - can player handle RTMP, Apple HLS, Adobe HDS, Microsoft HSS?&lt;br /&gt;
* Plugins support - can we use or develop community plugins easily?&lt;br /&gt;
* Embedding support - so users could post media content outside Moodle, if permitted.&lt;br /&gt;
* Maintainability of the links between the player and Moodle - how much work will we need to do every time we upgrade?&lt;br /&gt;
&lt;br /&gt;
== Candidates ==&lt;br /&gt;
&lt;br /&gt;
* [http://flowplayer.org/ Flowplayer HTML5]&lt;br /&gt;
* [http://www.videojs.com/ Video.JS]&lt;br /&gt;
* [http://www.projekktor.com/ Projekktor]&lt;br /&gt;
* ?Are there other alternatives?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Flowplayer HTML5&lt;br /&gt;
! Video.JS&lt;br /&gt;
! Projekktor&lt;br /&gt;
|-&lt;br /&gt;
! Accessible Player:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Keyboard control&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes (configurable)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Subtitles support&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via plugin)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Touch interface&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Appearance:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Skins&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* CSS customisation&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTL support&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
! Mobile platforms:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* iOS&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Android&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Streaming protocols:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTMP&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via playlist)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Adaptive HTTP&lt;br /&gt;
| HLS&lt;br /&gt;
| HLS (via plugin)&lt;br /&gt;
| HLS (via playlist)&lt;br /&gt;
|-&lt;br /&gt;
! Audio player&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Embedding support&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (configurable)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via addThis plugin)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via plugin)&lt;br /&gt;
|-&lt;br /&gt;
! License&lt;br /&gt;
| GPL v3 (with additional terms)&lt;br /&gt;
| Apache 2&lt;br /&gt;
| GPL v3&lt;br /&gt;
|-&lt;br /&gt;
! JS library&lt;br /&gt;
| jQuery&lt;br /&gt;
| -&lt;br /&gt;
| jQuery&lt;br /&gt;
|-&lt;br /&gt;
! Plugins infrastructure&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Flash fallback player&lt;br /&gt;
| Flowplayer Flash&lt;br /&gt;
| video-js flash&lt;br /&gt;
| StobeMediaPlayback (but can be jarisplayer or some other).&lt;br /&gt;
|-&lt;br /&gt;
! API&lt;br /&gt;
| Yes (plus window.flowplayer object)&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Flowplayer HTML5 ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* Good looking player, resembles existing flash flowplayer in Moodle (with &amp;quot;functional&amp;quot; skin)&lt;br /&gt;
* Extensive customisation (via CSS3 skins and configuration object)&lt;br /&gt;
* Streaming support (RTMP, HLS)&lt;br /&gt;
* Good accessibility features&lt;br /&gt;
* Configurable embedding functionality&lt;br /&gt;
* Existing flash flowplayer can be configured for fallback (the appearance of player will not be affected).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Require jQuery for functioning&lt;br /&gt;
* Flowplayer logo remains on screen&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using wrapper around &amp;lt;video&amp;gt;.&lt;br /&gt;
* width and height attributes in video tag are ignored, player size is configured via wrapper size only.&lt;br /&gt;
* RTMP server connection is configured via data-rtmp attribute in wrapper or player init config parameter, actual path the file specified in src attribute of source item.&lt;br /&gt;
* &amp;lt;source type=&amp;quot;video/flash&amp;quot;... dummy MIME type to force using plash player for whatever content.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Plugins infrastructure&lt;br /&gt;
* No audio support&lt;br /&gt;
&lt;br /&gt;
=== Video.JS ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Extensive API.&lt;br /&gt;
* No extra JS library needed.&lt;br /&gt;
* Many plugins.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Poor documentation&lt;br /&gt;
* RTMP requires non-standard MIME.&lt;br /&gt;
* Android and iOS override Video.JS with own player, when not overridden, content is not playing.&lt;br /&gt;
* No RTL.&lt;br /&gt;
* HLS support via plugin (many files to include, external contributor see https://github.com/videojs/videojs-contrib-hls).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* RTMP server connection and path specified as single URI in src attribute of source item, &#039;&amp;amp;&#039; character is used as server connection and path divider.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Embedded HLS support.&lt;br /&gt;
&lt;br /&gt;
=== Projekktor ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Well documented API.&lt;br /&gt;
* Media RSS support.&lt;br /&gt;
* Possibility to choose flash player for fallback (included by default are StrobeMediaPlayback and Jarisplayer, both Open Source).&lt;br /&gt;
* Platform preference order selection (e.g. browser, ios, android, flash, native).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Uses flash where it is not supposed to (e.g. mp4 in Chrome).&lt;br /&gt;
* Issues on ios and android (suggests to download file when play button is pressed).&lt;br /&gt;
* RTMP only work if defined via playlist rather than in &amp;lt;source&amp;gt; tags.&lt;br /&gt;
* Subtitles plugin is not free.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* Make sure &amp;lt;video&amp;gt; tag has class attribute with &#039;projekktor&#039; value (even if you initialise it by ID of the element), player will not work properly otherwise.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Cross-browser support ==&lt;br /&gt;
&lt;br /&gt;
=== Method ===&lt;br /&gt;
Compatibility checks were done manually by accessing the sample page using different browsers and platforms. Sample page contained the list of identical player instances, initialised for each &amp;lt;video&amp;gt; definition with a &amp;lt;source&amp;gt; of particular format: mp4, webm, ogg, flv. Streaming support was checked by setting up a &amp;lt;video&amp;gt; container with two sources of the same video, one was HLS (Apple HTTP Live Streaming) stream for browsers and platforms that support html5 video streaming, another one was RTMP which is played using flash engine and supposed to be used in case if HLS is not supported.&lt;br /&gt;
&lt;br /&gt;
=== Sample Pages ===&lt;br /&gt;
&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=flowplayer Flowplayer HTML5] version 5.4.6.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=videojs Video.JS] version 4.4.1.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=projekktor Projekktor] version 1.3.09.&lt;br /&gt;
&lt;br /&gt;
=== Source ===&lt;br /&gt;
&lt;br /&gt;
Source of testing page is hosted on [https://github.com/kabalin/test-html5-players/blob/master/players.php github]. The actual source of the html page can be viewed in browser.&lt;br /&gt;
&lt;br /&gt;
=== Discussion ===&lt;br /&gt;
&lt;br /&gt;
The players comparison that has been carried out demonstrated that &amp;quot;least hassle&amp;quot; player is Flowplayer. Despite some drawbacks listed in [[#Flowplayer_HTML5|corresponding section above]], it is clearly a winner as it works as expected and according to documentation for all browsers and platforms I had chance to test it. This is the only player that supports RTL layout, display platform incompatibility message prior to attempt to play, and was simple to configure (no undocumented tricks that I had to figure out to make it work). Both VideoJS and Projekktor do now perform properly in all cases. Among those two, I personally prefer Projekktor more for its extensive API, plugins infrastructure and configuration flexibility. However problems on mobile platforms and flash fallback inconsistency make them unreliable at this stage.&lt;br /&gt;
&lt;br /&gt;
=== Compatibility results ===&lt;br /&gt;
&lt;br /&gt;
The table was populated using Flowplayer as others do not perform good enough with some formats and platforms, e.g. VideoJS allow mobile platform player to override itself, Projekktor does not always use HTML5 where browser clearly can handle it (supported in native mode and Flowplayer).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Browser&lt;br /&gt;
! mp4&lt;br /&gt;
! webm&lt;br /&gt;
! ogg&lt;br /&gt;
! flv&lt;br /&gt;
! RTMP/HLS*&lt;br /&gt;
|-&lt;br /&gt;
! Windows 7&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Firefox 27.0.1&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 12.16&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 5.1.7&lt;br /&gt;
| flash&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Internet Explorer 11.0.9600.x&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Linux (Debian Wheezy)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.115&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! OSX 10.9&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 7.0 (9537.71)&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 phone (CyanogenMod, no flash)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 tablet (GalaxyTab2, flash app 11.1.115.36)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 19.0.1340.x&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
! iPhone 4S (6.1.3)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! iPad 4 (7.0.6)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;small&amp;gt;* For HLS/RTMP, html5 in the table means HLS has been used, flash means player fell back and used RTMP.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sub Tasks ==&lt;br /&gt;
&lt;br /&gt;
== Mock-Ups/Prototypes ==&lt;br /&gt;
&lt;br /&gt;
See [[#Sample_Pages|Sample pages]] section.&lt;br /&gt;
&lt;br /&gt;
== Related Tracker Issues ==&lt;br /&gt;
* MDL-38158&lt;br /&gt;
&lt;br /&gt;
== Useful links ==&lt;br /&gt;
* http://praegnanz.de/html5video/&lt;br /&gt;
* http://html5video.org/wiki/HTML5_Video_Player_Comparison&lt;br /&gt;
* http://www.streamingmedia.com/Articles/Editorial/Featured-Articles/Choosing-a-Video-Player-Features-and-Specs-for-the-Top-Five-94188.aspx&lt;br /&gt;
&lt;br /&gt;
[[Category:Project]]&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=44134</id>
		<title>HTML5 player</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=44134"/>
		<updated>2014-03-10T10:52:39Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: /* Video.JS */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}&lt;br /&gt;
{{Infobox Project&lt;br /&gt;
|name = HTML5 Player with flash fallback&lt;br /&gt;
|state = In Development&lt;br /&gt;
|tracker = https://tracker.moodle.org/browse/MDL-38158&lt;br /&gt;
|discussion = https://moodle.org/mod/forum/discuss.php?d=222753#p1105373&lt;br /&gt;
|assignee = [https://tracker.moodle.org/secure/ViewProfile.jspa?name=kabalin Ruslan Kabalin]&lt;br /&gt;
}}&lt;br /&gt;
{{Moodle 2.x}}&lt;br /&gt;
&lt;br /&gt;
== Project goals ==&lt;br /&gt;
&lt;br /&gt;
The purpose of this document is to choose HTML5 with flash fallback for integration in Moodle.&lt;br /&gt;
&lt;br /&gt;
The aim of this change is to reach a consistent look of the player among different platforms and browsers, as well as making sure that player starts using flash if html5 is not supported by browser for the given format. Another aim is to improve accessibility and usability, enhance customisation.&lt;br /&gt;
&lt;br /&gt;
== Considerations ==&lt;br /&gt;
&lt;br /&gt;
* Usability of the player - is it easy to use it and intuitively understand how to use controls?&lt;br /&gt;
* Accessibility of the player - possibility of keyboard navigation, subtitles, support?&lt;br /&gt;
* Appearance of the player - can its interface be modified, themes support, RTL?&lt;br /&gt;
* Consistency among browsers - does player look the same?&lt;br /&gt;
* Audio support - can player handle HTML5 &amp;lt;audio&amp;gt; tag?&lt;br /&gt;
* Mobile platforms support - does player also work on iOS and Android?&lt;br /&gt;
* Streaming media support (including adaptive-bitrate delivery) - can player handle RTMP, Apple HLS, Adobe HDS, Microsoft HSS?&lt;br /&gt;
* Plugins support - can we use or develop community plugins easily?&lt;br /&gt;
* Embedding support - so users could post media content outside Moodle, if permitted.&lt;br /&gt;
* Maintainability of the links between the player and Moodle - how much work will we need to do every time we upgrade?&lt;br /&gt;
&lt;br /&gt;
== Candidates ==&lt;br /&gt;
&lt;br /&gt;
* [http://flowplayer.org/ Flowplayer HTML5]&lt;br /&gt;
* [http://www.videojs.com/ Video.JS]&lt;br /&gt;
* [http://www.projekktor.com/ Projekktor]&lt;br /&gt;
* ?Are there other alternatives?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Flowplayer HTML5&lt;br /&gt;
! Video.JS&lt;br /&gt;
! Projekktor&lt;br /&gt;
|-&lt;br /&gt;
! Accessible Player:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Keyboard control&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes (configurable)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Subtitles support&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via plugin)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Touch interface&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Appearance:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Skins&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* CSS customisation&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTL support&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
! Mobile platforms:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* iOS&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Android&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Streaming protocols:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTMP&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via playlist)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Adaptive HTTP&lt;br /&gt;
| HLS&lt;br /&gt;
| HLS (via plugin)&lt;br /&gt;
| HLS (via playlist)&lt;br /&gt;
|-&lt;br /&gt;
! Audio player&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Embedding support&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (configurable)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via addThis plugin)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via plugin)&lt;br /&gt;
|-&lt;br /&gt;
! License&lt;br /&gt;
| GPL v3 (with additional terms)&lt;br /&gt;
| Apache 2&lt;br /&gt;
| GPL v3&lt;br /&gt;
|-&lt;br /&gt;
! JS library&lt;br /&gt;
| jQuery&lt;br /&gt;
| -&lt;br /&gt;
| jQuery&lt;br /&gt;
|-&lt;br /&gt;
! Plugins infrastructure&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Flash fallback player&lt;br /&gt;
| Flowplayer Flash&lt;br /&gt;
| video-js flash&lt;br /&gt;
| StobeMediaPlayback (but can be jarisplayer or some other).&lt;br /&gt;
|-&lt;br /&gt;
! API&lt;br /&gt;
| Yes (plus window.flowplayer object)&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Flowplayer HTML5 ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* Good looking player, resembles existing flash flowplayer in Moodle (with &amp;quot;functional&amp;quot; skin)&lt;br /&gt;
* Extensive customisation (via CSS3 skins and configuration object)&lt;br /&gt;
* Streaming support (RTMP, HLS)&lt;br /&gt;
* Good accessibility features&lt;br /&gt;
* Configurable embedding functionality&lt;br /&gt;
* Existing flash flowplayer can be configured for fallback (the appearance of player will not be affected).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Require jQuery for functioning&lt;br /&gt;
* Flowplayer logo remains on screen&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using wrapper around &amp;lt;video&amp;gt;.&lt;br /&gt;
* width and height attributes in video tag are ignored, player size is configured via wrapper size only.&lt;br /&gt;
* RTMP server connection is configured via data-rtmp attribute in wrapper or player init config parameter, actual path the file specified in src attribute of source item.&lt;br /&gt;
* &amp;lt;source type=&amp;quot;video/flash&amp;quot;... dummy MIME type to force using plash player for whatever content.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Plugins infrastructure&lt;br /&gt;
* No audio support&lt;br /&gt;
&lt;br /&gt;
=== Video.JS ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Extensive API.&lt;br /&gt;
* No extra JS library needed.&lt;br /&gt;
* Many plugins.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Poor documentation&lt;br /&gt;
* RTMP requires non-standard MIME.&lt;br /&gt;
* Android and iOS override Video.JS with own player, when not overridden, content is not playing.&lt;br /&gt;
* No RTL.&lt;br /&gt;
* HLS support via plugin (many files to include, external contributor see https://github.com/videojs/videojs-contrib-hls).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* RTMP server connection and path specified as single URI in src attribute of source item, &#039;&amp;amp;&#039; character is used as server connection and path divider.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Embedded HLS support.&lt;br /&gt;
&lt;br /&gt;
=== Projekktor ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Well documented API.&lt;br /&gt;
* Media RSS support.&lt;br /&gt;
* Possibility to choose flash player for fallback (included by default are StrobeMediaPlayback and Jarisplayer, both Open Source).&lt;br /&gt;
* Platform preference order selection (e.g. browser, ios, android, flash, native).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Uses flash where it is not supposed to (e.g. mp4 in Chrome).&lt;br /&gt;
* Issues on ios and android (suggests to download file when play button is pressed).&lt;br /&gt;
* RTMP only work if defined via playlist rather than in &amp;lt;source&amp;gt; tags.&lt;br /&gt;
* Subtitles plugin is not free.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* Make sure &amp;lt;video&amp;gt; tag has class attribute with &#039;projekktor&#039; value (even if you initialise it by ID of the element), player will not work properly otherwise.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Cross-browser support ==&lt;br /&gt;
&lt;br /&gt;
=== Method ===&lt;br /&gt;
Compatibility checks were done manually by accessing the sample page using different browsers and platforms. Sample page contained the list of identical player instances, initialised for each &amp;lt;video&amp;gt; definition with a &amp;lt;source&amp;gt; of particular format: mp4, webm, ogg, flv. Streaming support was checked by setting up a &amp;lt;video&amp;gt; container with two sources of the same video, one was HLS (Apple HTTP Live Streaming) stream for browsers and platforms that support html5 video streaming, another one was RTMP which is played using flash engine and supposed to be used in case if HLS is not supported.&lt;br /&gt;
&lt;br /&gt;
=== Sample Pages ===&lt;br /&gt;
&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=flowplayer Flowplayer HTML5] version 5.4.6.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=videojs Video.JS] version 4.4.1.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=projekktor Projekktor] version 1.3.09.&lt;br /&gt;
&lt;br /&gt;
=== Source ===&lt;br /&gt;
&lt;br /&gt;
Source of testing page is hosted on [https://github.com/kabalin/test-html5-players/blob/master/players.php github]. The actual source of the html page can be viewed in browser.&lt;br /&gt;
&lt;br /&gt;
=== Discussion ===&lt;br /&gt;
&lt;br /&gt;
The players comparison that has been carried out demonstrated that &amp;quot;least hassle&amp;quot; player is Flowplayer. Despite some drawbacks listed in [[#Flowplayer_HTML5|corresponding section above]], it is clearly a winner as it works as expected and according to documentation for all browsers and platforms I had chance to test it. This is the only player that supports RTL layout, display platform incompatibility message prior to attempt to play, and was simple to configure (no undocumented tricks that I had to figure out to make it work). Both VideoJS and Projekktor do now perform properly in all cases. Among those two, I personally prefer Projekktor more for its extensive API, plugins infrastructure and configuration flexibility. However problems on mobile platforms and flash fallback inconsistency make them unreliable at this stage.&lt;br /&gt;
&lt;br /&gt;
=== Compatibility results ===&lt;br /&gt;
&lt;br /&gt;
The table was populated using Flowplayer as others do not perform good enough with some formats and platforms, e.g. VideoJS allow mobile platform player to override itself, Projekktor does not always use HTML5 where browser clearly can handle it (supported in native mode and Flowplayer).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Browser&lt;br /&gt;
! mp4&lt;br /&gt;
! webm&lt;br /&gt;
! ogg&lt;br /&gt;
! flv&lt;br /&gt;
! RTMP/HLS*&lt;br /&gt;
|-&lt;br /&gt;
! Windows 7&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Firefox 27.0.1&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 12.16&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 5.1.7&lt;br /&gt;
| flash&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Internet Explorer 11.0.9600.x&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Linux (Debian Wheezy)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.115&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! OSX 10.9&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 7.0 (9537.71)&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 phone (CyanogenMod, no flash)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 tablet (GalaxyTab2, flash app 11.1.115.36)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 19.0.1340.x&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
! iPhone 4S (6.1.3)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! iPad 4 (7.0.6)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;small&amp;gt;* For HLS/RTMP, html5 in the table means HLS has been used, flash means player fell back and used RTMP.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sub Tasks ==&lt;br /&gt;
&lt;br /&gt;
== Mock-Ups/Prototypes ==&lt;br /&gt;
&lt;br /&gt;
== Related Tracker Issues ==&lt;br /&gt;
* MDL-38158&lt;br /&gt;
&lt;br /&gt;
== Useful links ==&lt;br /&gt;
* http://praegnanz.de/html5video/&lt;br /&gt;
* http://html5video.org/wiki/HTML5_Video_Player_Comparison&lt;br /&gt;
* http://www.streamingmedia.com/Articles/Editorial/Featured-Articles/Choosing-a-Video-Player-Features-and-Specs-for-the-Top-Five-94188.aspx&lt;br /&gt;
&lt;br /&gt;
[[Category:Project]]&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=44133</id>
		<title>HTML5 player</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=44133"/>
		<updated>2014-03-10T10:51:28Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: /* Discussion */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}&lt;br /&gt;
{{Infobox Project&lt;br /&gt;
|name = HTML5 Player with flash fallback&lt;br /&gt;
|state = In Development&lt;br /&gt;
|tracker = https://tracker.moodle.org/browse/MDL-38158&lt;br /&gt;
|discussion = https://moodle.org/mod/forum/discuss.php?d=222753#p1105373&lt;br /&gt;
|assignee = [https://tracker.moodle.org/secure/ViewProfile.jspa?name=kabalin Ruslan Kabalin]&lt;br /&gt;
}}&lt;br /&gt;
{{Moodle 2.x}}&lt;br /&gt;
&lt;br /&gt;
== Project goals ==&lt;br /&gt;
&lt;br /&gt;
The purpose of this document is to choose HTML5 with flash fallback for integration in Moodle.&lt;br /&gt;
&lt;br /&gt;
The aim of this change is to reach a consistent look of the player among different platforms and browsers, as well as making sure that player starts using flash if html5 is not supported by browser for the given format. Another aim is to improve accessibility and usability, enhance customisation.&lt;br /&gt;
&lt;br /&gt;
== Considerations ==&lt;br /&gt;
&lt;br /&gt;
* Usability of the player - is it easy to use it and intuitively understand how to use controls?&lt;br /&gt;
* Accessibility of the player - possibility of keyboard navigation, subtitles, support?&lt;br /&gt;
* Appearance of the player - can its interface be modified, themes support, RTL?&lt;br /&gt;
* Consistency among browsers - does player look the same?&lt;br /&gt;
* Audio support - can player handle HTML5 &amp;lt;audio&amp;gt; tag?&lt;br /&gt;
* Mobile platforms support - does player also work on iOS and Android?&lt;br /&gt;
* Streaming media support (including adaptive-bitrate delivery) - can player handle RTMP, Apple HLS, Adobe HDS, Microsoft HSS?&lt;br /&gt;
* Plugins support - can we use or develop community plugins easily?&lt;br /&gt;
* Embedding support - so users could post media content outside Moodle, if permitted.&lt;br /&gt;
* Maintainability of the links between the player and Moodle - how much work will we need to do every time we upgrade?&lt;br /&gt;
&lt;br /&gt;
== Candidates ==&lt;br /&gt;
&lt;br /&gt;
* [http://flowplayer.org/ Flowplayer HTML5]&lt;br /&gt;
* [http://www.videojs.com/ Video.JS]&lt;br /&gt;
* [http://www.projekktor.com/ Projekktor]&lt;br /&gt;
* ?Are there other alternatives?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Flowplayer HTML5&lt;br /&gt;
! Video.JS&lt;br /&gt;
! Projekktor&lt;br /&gt;
|-&lt;br /&gt;
! Accessible Player:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Keyboard control&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes (configurable)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Subtitles support&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via plugin)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Touch interface&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Appearance:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Skins&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* CSS customisation&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTL support&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
! Mobile platforms:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* iOS&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Android&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Streaming protocols:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTMP&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via playlist)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Adaptive HTTP&lt;br /&gt;
| HLS&lt;br /&gt;
| HLS (via plugin)&lt;br /&gt;
| HLS (via playlist)&lt;br /&gt;
|-&lt;br /&gt;
! Audio player&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Embedding support&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (configurable)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via addThis plugin)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via plugin)&lt;br /&gt;
|-&lt;br /&gt;
! License&lt;br /&gt;
| GPL v3 (with additional terms)&lt;br /&gt;
| Apache 2&lt;br /&gt;
| GPL v3&lt;br /&gt;
|-&lt;br /&gt;
! JS library&lt;br /&gt;
| jQuery&lt;br /&gt;
| -&lt;br /&gt;
| jQuery&lt;br /&gt;
|-&lt;br /&gt;
! Plugins infrastructure&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Flash fallback player&lt;br /&gt;
| Flowplayer Flash&lt;br /&gt;
| video-js flash&lt;br /&gt;
| StobeMediaPlayback (but can be jarisplayer or some other).&lt;br /&gt;
|-&lt;br /&gt;
! API&lt;br /&gt;
| Yes (plus window.flowplayer object)&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Flowplayer HTML5 ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* Good looking player, resembles existing flash flowplayer in Moodle (with &amp;quot;functional&amp;quot; skin)&lt;br /&gt;
* Extensive customisation (via CSS3 skins and configuration object)&lt;br /&gt;
* Streaming support (RTMP, HLS)&lt;br /&gt;
* Good accessibility features&lt;br /&gt;
* Configurable embedding functionality&lt;br /&gt;
* Existing flash flowplayer can be configured for fallback (the appearance of player will not be affected).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Require jQuery for functioning&lt;br /&gt;
* Flowplayer logo remains on screen&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using wrapper around &amp;lt;video&amp;gt;.&lt;br /&gt;
* width and height attributes in video tag are ignored, player size is configured via wrapper size only.&lt;br /&gt;
* RTMP server connection is configured via data-rtmp attribute in wrapper or player init config parameter, actual path the file specified in src attribute of source item.&lt;br /&gt;
* &amp;lt;source type=&amp;quot;video/flash&amp;quot;... dummy MIME type to force using plash player for whatever content.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Plugins infrastructure&lt;br /&gt;
* No audio support&lt;br /&gt;
&lt;br /&gt;
=== Video.JS ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Extensive API.&lt;br /&gt;
* No extra JS library needed.&lt;br /&gt;
* Many plugins.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* RTMP requires non-standard MIME.&lt;br /&gt;
* Android and iOS override Video.JS with own player, when not overridden, content is not playing.&lt;br /&gt;
* No RTL.&lt;br /&gt;
* HLS support via plugin (many files to include, external contributor see https://github.com/videojs/videojs-contrib-hls).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* RTMP server connection and path specified as single URI in src attribute of source item, &#039;&amp;amp;&#039; character is used as server connection and path divider.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Embedded HLS support.&lt;br /&gt;
&lt;br /&gt;
=== Projekktor ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Well documented API.&lt;br /&gt;
* Media RSS support.&lt;br /&gt;
* Possibility to choose flash player for fallback (included by default are StrobeMediaPlayback and Jarisplayer, both Open Source).&lt;br /&gt;
* Platform preference order selection (e.g. browser, ios, android, flash, native).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Uses flash where it is not supposed to (e.g. mp4 in Chrome).&lt;br /&gt;
* Issues on ios and android (suggests to download file when play button is pressed).&lt;br /&gt;
* RTMP only work if defined via playlist rather than in &amp;lt;source&amp;gt; tags.&lt;br /&gt;
* Subtitles plugin is not free.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* Make sure &amp;lt;video&amp;gt; tag has class attribute with &#039;projekktor&#039; value (even if you initialise it by ID of the element), player will not work properly otherwise.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Cross-browser support ==&lt;br /&gt;
&lt;br /&gt;
=== Method ===&lt;br /&gt;
Compatibility checks were done manually by accessing the sample page using different browsers and platforms. Sample page contained the list of identical player instances, initialised for each &amp;lt;video&amp;gt; definition with a &amp;lt;source&amp;gt; of particular format: mp4, webm, ogg, flv. Streaming support was checked by setting up a &amp;lt;video&amp;gt; container with two sources of the same video, one was HLS (Apple HTTP Live Streaming) stream for browsers and platforms that support html5 video streaming, another one was RTMP which is played using flash engine and supposed to be used in case if HLS is not supported.&lt;br /&gt;
&lt;br /&gt;
=== Sample Pages ===&lt;br /&gt;
&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=flowplayer Flowplayer HTML5] version 5.4.6.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=videojs Video.JS] version 4.4.1.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=projekktor Projekktor] version 1.3.09.&lt;br /&gt;
&lt;br /&gt;
=== Source ===&lt;br /&gt;
&lt;br /&gt;
Source of testing page is hosted on [https://github.com/kabalin/test-html5-players/blob/master/players.php github]. The actual source of the html page can be viewed in browser.&lt;br /&gt;
&lt;br /&gt;
=== Discussion ===&lt;br /&gt;
&lt;br /&gt;
The players comparison that has been carried out demonstrated that &amp;quot;least hassle&amp;quot; player is Flowplayer. Despite some drawbacks listed in [[#Flowplayer_HTML5|corresponding section above]], it is clearly a winner as it works as expected and according to documentation for all browsers and platforms I had chance to test it. This is the only player that supports RTL layout, display platform incompatibility message prior to attempt to play, and was simple to configure (no undocumented tricks that I had to figure out to make it work). Both VideoJS and Projekktor do now perform properly in all cases. Among those two, I personally prefer Projekktor more for its extensive API, plugins infrastructure and configuration flexibility. However problems on mobile platforms and flash fallback inconsistency make them unreliable at this stage.&lt;br /&gt;
&lt;br /&gt;
=== Compatibility results ===&lt;br /&gt;
&lt;br /&gt;
The table was populated using Flowplayer as others do not perform good enough with some formats and platforms, e.g. VideoJS allow mobile platform player to override itself, Projekktor does not always use HTML5 where browser clearly can handle it (supported in native mode and Flowplayer).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Browser&lt;br /&gt;
! mp4&lt;br /&gt;
! webm&lt;br /&gt;
! ogg&lt;br /&gt;
! flv&lt;br /&gt;
! RTMP/HLS*&lt;br /&gt;
|-&lt;br /&gt;
! Windows 7&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Firefox 27.0.1&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 12.16&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 5.1.7&lt;br /&gt;
| flash&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Internet Explorer 11.0.9600.x&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Linux (Debian Wheezy)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.115&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! OSX 10.9&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 7.0 (9537.71)&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 phone (CyanogenMod, no flash)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 tablet (GalaxyTab2, flash app 11.1.115.36)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 19.0.1340.x&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
! iPhone 4S (6.1.3)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! iPad 4 (7.0.6)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;small&amp;gt;* For HLS/RTMP, html5 in the table means HLS has been used, flash means player fell back and used RTMP.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sub Tasks ==&lt;br /&gt;
&lt;br /&gt;
== Mock-Ups/Prototypes ==&lt;br /&gt;
&lt;br /&gt;
== Related Tracker Issues ==&lt;br /&gt;
* MDL-38158&lt;br /&gt;
&lt;br /&gt;
== Useful links ==&lt;br /&gt;
* http://praegnanz.de/html5video/&lt;br /&gt;
* http://html5video.org/wiki/HTML5_Video_Player_Comparison&lt;br /&gt;
* http://www.streamingmedia.com/Articles/Editorial/Featured-Articles/Choosing-a-Video-Player-Features-and-Specs-for-the-Top-Five-94188.aspx&lt;br /&gt;
&lt;br /&gt;
[[Category:Project]]&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=44132</id>
		<title>HTML5 player</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=44132"/>
		<updated>2014-03-10T10:50:27Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: /* Discussion */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}&lt;br /&gt;
{{Infobox Project&lt;br /&gt;
|name = HTML5 Player with flash fallback&lt;br /&gt;
|state = In Development&lt;br /&gt;
|tracker = https://tracker.moodle.org/browse/MDL-38158&lt;br /&gt;
|discussion = https://moodle.org/mod/forum/discuss.php?d=222753#p1105373&lt;br /&gt;
|assignee = [https://tracker.moodle.org/secure/ViewProfile.jspa?name=kabalin Ruslan Kabalin]&lt;br /&gt;
}}&lt;br /&gt;
{{Moodle 2.x}}&lt;br /&gt;
&lt;br /&gt;
== Project goals ==&lt;br /&gt;
&lt;br /&gt;
The purpose of this document is to choose HTML5 with flash fallback for integration in Moodle.&lt;br /&gt;
&lt;br /&gt;
The aim of this change is to reach a consistent look of the player among different platforms and browsers, as well as making sure that player starts using flash if html5 is not supported by browser for the given format. Another aim is to improve accessibility and usability, enhance customisation.&lt;br /&gt;
&lt;br /&gt;
== Considerations ==&lt;br /&gt;
&lt;br /&gt;
* Usability of the player - is it easy to use it and intuitively understand how to use controls?&lt;br /&gt;
* Accessibility of the player - possibility of keyboard navigation, subtitles, support?&lt;br /&gt;
* Appearance of the player - can its interface be modified, themes support, RTL?&lt;br /&gt;
* Consistency among browsers - does player look the same?&lt;br /&gt;
* Audio support - can player handle HTML5 &amp;lt;audio&amp;gt; tag?&lt;br /&gt;
* Mobile platforms support - does player also work on iOS and Android?&lt;br /&gt;
* Streaming media support (including adaptive-bitrate delivery) - can player handle RTMP, Apple HLS, Adobe HDS, Microsoft HSS?&lt;br /&gt;
* Plugins support - can we use or develop community plugins easily?&lt;br /&gt;
* Embedding support - so users could post media content outside Moodle, if permitted.&lt;br /&gt;
* Maintainability of the links between the player and Moodle - how much work will we need to do every time we upgrade?&lt;br /&gt;
&lt;br /&gt;
== Candidates ==&lt;br /&gt;
&lt;br /&gt;
* [http://flowplayer.org/ Flowplayer HTML5]&lt;br /&gt;
* [http://www.videojs.com/ Video.JS]&lt;br /&gt;
* [http://www.projekktor.com/ Projekktor]&lt;br /&gt;
* ?Are there other alternatives?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Flowplayer HTML5&lt;br /&gt;
! Video.JS&lt;br /&gt;
! Projekktor&lt;br /&gt;
|-&lt;br /&gt;
! Accessible Player:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Keyboard control&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes (configurable)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Subtitles support&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via plugin)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Touch interface&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Appearance:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Skins&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* CSS customisation&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTL support&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
! Mobile platforms:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* iOS&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Android&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Streaming protocols:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTMP&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via playlist)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Adaptive HTTP&lt;br /&gt;
| HLS&lt;br /&gt;
| HLS (via plugin)&lt;br /&gt;
| HLS (via playlist)&lt;br /&gt;
|-&lt;br /&gt;
! Audio player&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Embedding support&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (configurable)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via addThis plugin)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via plugin)&lt;br /&gt;
|-&lt;br /&gt;
! License&lt;br /&gt;
| GPL v3 (with additional terms)&lt;br /&gt;
| Apache 2&lt;br /&gt;
| GPL v3&lt;br /&gt;
|-&lt;br /&gt;
! JS library&lt;br /&gt;
| jQuery&lt;br /&gt;
| -&lt;br /&gt;
| jQuery&lt;br /&gt;
|-&lt;br /&gt;
! Plugins infrastructure&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Flash fallback player&lt;br /&gt;
| Flowplayer Flash&lt;br /&gt;
| video-js flash&lt;br /&gt;
| StobeMediaPlayback (but can be jarisplayer or some other).&lt;br /&gt;
|-&lt;br /&gt;
! API&lt;br /&gt;
| Yes (plus window.flowplayer object)&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Flowplayer HTML5 ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* Good looking player, resembles existing flash flowplayer in Moodle (with &amp;quot;functional&amp;quot; skin)&lt;br /&gt;
* Extensive customisation (via CSS3 skins and configuration object)&lt;br /&gt;
* Streaming support (RTMP, HLS)&lt;br /&gt;
* Good accessibility features&lt;br /&gt;
* Configurable embedding functionality&lt;br /&gt;
* Existing flash flowplayer can be configured for fallback (the appearance of player will not be affected).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Require jQuery for functioning&lt;br /&gt;
* Flowplayer logo remains on screen&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using wrapper around &amp;lt;video&amp;gt;.&lt;br /&gt;
* width and height attributes in video tag are ignored, player size is configured via wrapper size only.&lt;br /&gt;
* RTMP server connection is configured via data-rtmp attribute in wrapper or player init config parameter, actual path the file specified in src attribute of source item.&lt;br /&gt;
* &amp;lt;source type=&amp;quot;video/flash&amp;quot;... dummy MIME type to force using plash player for whatever content.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Plugins infrastructure&lt;br /&gt;
* No audio support&lt;br /&gt;
&lt;br /&gt;
=== Video.JS ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Extensive API.&lt;br /&gt;
* No extra JS library needed.&lt;br /&gt;
* Many plugins.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* RTMP requires non-standard MIME.&lt;br /&gt;
* Android and iOS override Video.JS with own player, when not overridden, content is not playing.&lt;br /&gt;
* No RTL.&lt;br /&gt;
* HLS support via plugin (many files to include, external contributor see https://github.com/videojs/videojs-contrib-hls).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* RTMP server connection and path specified as single URI in src attribute of source item, &#039;&amp;amp;&#039; character is used as server connection and path divider.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Embedded HLS support.&lt;br /&gt;
&lt;br /&gt;
=== Projekktor ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Well documented API.&lt;br /&gt;
* Media RSS support.&lt;br /&gt;
* Possibility to choose flash player for fallback (included by default are StrobeMediaPlayback and Jarisplayer, both Open Source).&lt;br /&gt;
* Platform preference order selection (e.g. browser, ios, android, flash, native).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Uses flash where it is not supposed to (e.g. mp4 in Chrome).&lt;br /&gt;
* Issues on ios and android (suggests to download file when play button is pressed).&lt;br /&gt;
* RTMP only work if defined via playlist rather than in &amp;lt;source&amp;gt; tags.&lt;br /&gt;
* Subtitles plugin is not free.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* Make sure &amp;lt;video&amp;gt; tag has class attribute with &#039;projekktor&#039; value (even if you initialise it by ID of the element), player will not work properly otherwise.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Cross-browser support ==&lt;br /&gt;
&lt;br /&gt;
=== Method ===&lt;br /&gt;
Compatibility checks were done manually by accessing the sample page using different browsers and platforms. Sample page contained the list of identical player instances, initialised for each &amp;lt;video&amp;gt; definition with a &amp;lt;source&amp;gt; of particular format: mp4, webm, ogg, flv. Streaming support was checked by setting up a &amp;lt;video&amp;gt; container with two sources of the same video, one was HLS (Apple HTTP Live Streaming) stream for browsers and platforms that support html5 video streaming, another one was RTMP which is played using flash engine and supposed to be used in case if HLS is not supported.&lt;br /&gt;
&lt;br /&gt;
=== Sample Pages ===&lt;br /&gt;
&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=flowplayer Flowplayer HTML5] version 5.4.6.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=videojs Video.JS] version 4.4.1.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=projekktor Projekktor] version 1.3.09.&lt;br /&gt;
&lt;br /&gt;
=== Source ===&lt;br /&gt;
&lt;br /&gt;
Source of testing page is hosted on [https://github.com/kabalin/test-html5-players/blob/master/players.php github]. The actual source of the html page can be viewed in browser.&lt;br /&gt;
&lt;br /&gt;
=== Discussion ===&lt;br /&gt;
&lt;br /&gt;
The players comparison that has been carried out demonstrated that &amp;quot;least hassle&amp;quot; player is Flowplayer. Despite some drawbacks listed in corresponding section above, it is clearly a winner as it works as expected and according to documentation for all browsers and platforms I had chance to test it. This is the only player that supports RTL layout, display platform incompatibility message prior to attempt to play, and was simple to configure (no undocumented tricks that I had to figure out to make it work). Both VideoJS and Projekktor do now perform properly in all cases. Among those two, I personally prefer Projekktor more for its extensive API, plugins infrastructure and configuration flexibility. However problems on mobile platforms and flash fallback inconsistency make them unreliable at this stage.&lt;br /&gt;
&lt;br /&gt;
=== Compatibility results ===&lt;br /&gt;
&lt;br /&gt;
The table was populated using Flowplayer as others do not perform good enough with some formats and platforms, e.g. VideoJS allow mobile platform player to override itself, Projekktor does not always use HTML5 where browser clearly can handle it (supported in native mode and Flowplayer).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Browser&lt;br /&gt;
! mp4&lt;br /&gt;
! webm&lt;br /&gt;
! ogg&lt;br /&gt;
! flv&lt;br /&gt;
! RTMP/HLS*&lt;br /&gt;
|-&lt;br /&gt;
! Windows 7&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Firefox 27.0.1&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 12.16&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 5.1.7&lt;br /&gt;
| flash&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Internet Explorer 11.0.9600.x&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Linux (Debian Wheezy)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.115&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! OSX 10.9&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 7.0 (9537.71)&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 phone (CyanogenMod, no flash)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 tablet (GalaxyTab2, flash app 11.1.115.36)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 19.0.1340.x&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
! iPhone 4S (6.1.3)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! iPad 4 (7.0.6)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;small&amp;gt;* For HLS/RTMP, html5 in the table means HLS has been used, flash means player fell back and used RTMP.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sub Tasks ==&lt;br /&gt;
&lt;br /&gt;
== Mock-Ups/Prototypes ==&lt;br /&gt;
&lt;br /&gt;
== Related Tracker Issues ==&lt;br /&gt;
* MDL-38158&lt;br /&gt;
&lt;br /&gt;
== Useful links ==&lt;br /&gt;
* http://praegnanz.de/html5video/&lt;br /&gt;
* http://html5video.org/wiki/HTML5_Video_Player_Comparison&lt;br /&gt;
* http://www.streamingmedia.com/Articles/Editorial/Featured-Articles/Choosing-a-Video-Player-Features-and-Specs-for-the-Top-Five-94188.aspx&lt;br /&gt;
&lt;br /&gt;
[[Category:Project]]&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=44131</id>
		<title>HTML5 player</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=44131"/>
		<updated>2014-03-10T10:47:54Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: /* Projekktor */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}&lt;br /&gt;
{{Infobox Project&lt;br /&gt;
|name = HTML5 Player with flash fallback&lt;br /&gt;
|state = In Development&lt;br /&gt;
|tracker = https://tracker.moodle.org/browse/MDL-38158&lt;br /&gt;
|discussion = https://moodle.org/mod/forum/discuss.php?d=222753#p1105373&lt;br /&gt;
|assignee = [https://tracker.moodle.org/secure/ViewProfile.jspa?name=kabalin Ruslan Kabalin]&lt;br /&gt;
}}&lt;br /&gt;
{{Moodle 2.x}}&lt;br /&gt;
&lt;br /&gt;
== Project goals ==&lt;br /&gt;
&lt;br /&gt;
The purpose of this document is to choose HTML5 with flash fallback for integration in Moodle.&lt;br /&gt;
&lt;br /&gt;
The aim of this change is to reach a consistent look of the player among different platforms and browsers, as well as making sure that player starts using flash if html5 is not supported by browser for the given format. Another aim is to improve accessibility and usability, enhance customisation.&lt;br /&gt;
&lt;br /&gt;
== Considerations ==&lt;br /&gt;
&lt;br /&gt;
* Usability of the player - is it easy to use it and intuitively understand how to use controls?&lt;br /&gt;
* Accessibility of the player - possibility of keyboard navigation, subtitles, support?&lt;br /&gt;
* Appearance of the player - can its interface be modified, themes support, RTL?&lt;br /&gt;
* Consistency among browsers - does player look the same?&lt;br /&gt;
* Audio support - can player handle HTML5 &amp;lt;audio&amp;gt; tag?&lt;br /&gt;
* Mobile platforms support - does player also work on iOS and Android?&lt;br /&gt;
* Streaming media support (including adaptive-bitrate delivery) - can player handle RTMP, Apple HLS, Adobe HDS, Microsoft HSS?&lt;br /&gt;
* Plugins support - can we use or develop community plugins easily?&lt;br /&gt;
* Embedding support - so users could post media content outside Moodle, if permitted.&lt;br /&gt;
* Maintainability of the links between the player and Moodle - how much work will we need to do every time we upgrade?&lt;br /&gt;
&lt;br /&gt;
== Candidates ==&lt;br /&gt;
&lt;br /&gt;
* [http://flowplayer.org/ Flowplayer HTML5]&lt;br /&gt;
* [http://www.videojs.com/ Video.JS]&lt;br /&gt;
* [http://www.projekktor.com/ Projekktor]&lt;br /&gt;
* ?Are there other alternatives?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Flowplayer HTML5&lt;br /&gt;
! Video.JS&lt;br /&gt;
! Projekktor&lt;br /&gt;
|-&lt;br /&gt;
! Accessible Player:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Keyboard control&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes (configurable)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Subtitles support&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via plugin)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Touch interface&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Appearance:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Skins&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* CSS customisation&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTL support&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
! Mobile platforms:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* iOS&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Android&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Streaming protocols:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTMP&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via playlist)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Adaptive HTTP&lt;br /&gt;
| HLS&lt;br /&gt;
| HLS (via plugin)&lt;br /&gt;
| HLS (via playlist)&lt;br /&gt;
|-&lt;br /&gt;
! Audio player&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Embedding support&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (configurable)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via addThis plugin)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via plugin)&lt;br /&gt;
|-&lt;br /&gt;
! License&lt;br /&gt;
| GPL v3 (with additional terms)&lt;br /&gt;
| Apache 2&lt;br /&gt;
| GPL v3&lt;br /&gt;
|-&lt;br /&gt;
! JS library&lt;br /&gt;
| jQuery&lt;br /&gt;
| -&lt;br /&gt;
| jQuery&lt;br /&gt;
|-&lt;br /&gt;
! Plugins infrastructure&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Flash fallback player&lt;br /&gt;
| Flowplayer Flash&lt;br /&gt;
| video-js flash&lt;br /&gt;
| StobeMediaPlayback (but can be jarisplayer or some other).&lt;br /&gt;
|-&lt;br /&gt;
! API&lt;br /&gt;
| Yes (plus window.flowplayer object)&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Flowplayer HTML5 ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* Good looking player, resembles existing flash flowplayer in Moodle (with &amp;quot;functional&amp;quot; skin)&lt;br /&gt;
* Extensive customisation (via CSS3 skins and configuration object)&lt;br /&gt;
* Streaming support (RTMP, HLS)&lt;br /&gt;
* Good accessibility features&lt;br /&gt;
* Configurable embedding functionality&lt;br /&gt;
* Existing flash flowplayer can be configured for fallback (the appearance of player will not be affected).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Require jQuery for functioning&lt;br /&gt;
* Flowplayer logo remains on screen&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using wrapper around &amp;lt;video&amp;gt;.&lt;br /&gt;
* width and height attributes in video tag are ignored, player size is configured via wrapper size only.&lt;br /&gt;
* RTMP server connection is configured via data-rtmp attribute in wrapper or player init config parameter, actual path the file specified in src attribute of source item.&lt;br /&gt;
* &amp;lt;source type=&amp;quot;video/flash&amp;quot;... dummy MIME type to force using plash player for whatever content.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Plugins infrastructure&lt;br /&gt;
* No audio support&lt;br /&gt;
&lt;br /&gt;
=== Video.JS ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Extensive API.&lt;br /&gt;
* No extra JS library needed.&lt;br /&gt;
* Many plugins.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* RTMP requires non-standard MIME.&lt;br /&gt;
* Android and iOS override Video.JS with own player, when not overridden, content is not playing.&lt;br /&gt;
* No RTL.&lt;br /&gt;
* HLS support via plugin (many files to include, external contributor see https://github.com/videojs/videojs-contrib-hls).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* RTMP server connection and path specified as single URI in src attribute of source item, &#039;&amp;amp;&#039; character is used as server connection and path divider.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Embedded HLS support.&lt;br /&gt;
&lt;br /&gt;
=== Projekktor ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Well documented API.&lt;br /&gt;
* Media RSS support.&lt;br /&gt;
* Possibility to choose flash player for fallback (included by default are StrobeMediaPlayback and Jarisplayer, both Open Source).&lt;br /&gt;
* Platform preference order selection (e.g. browser, ios, android, flash, native).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Uses flash where it is not supposed to (e.g. mp4 in Chrome).&lt;br /&gt;
* Issues on ios and android (suggests to download file when play button is pressed).&lt;br /&gt;
* RTMP only work if defined via playlist rather than in &amp;lt;source&amp;gt; tags.&lt;br /&gt;
* Subtitles plugin is not free.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* Make sure &amp;lt;video&amp;gt; tag has class attribute with &#039;projekktor&#039; value (even if you initialise it by ID of the element), player will not work properly otherwise.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Cross-browser support ==&lt;br /&gt;
&lt;br /&gt;
=== Method ===&lt;br /&gt;
Compatibility checks were done manually by accessing the sample page using different browsers and platforms. Sample page contained the list of identical player instances, initialised for each &amp;lt;video&amp;gt; definition with a &amp;lt;source&amp;gt; of particular format: mp4, webm, ogg, flv. Streaming support was checked by setting up a &amp;lt;video&amp;gt; container with two sources of the same video, one was HLS (Apple HTTP Live Streaming) stream for browsers and platforms that support html5 video streaming, another one was RTMP which is played using flash engine and supposed to be used in case if HLS is not supported.&lt;br /&gt;
&lt;br /&gt;
=== Sample Pages ===&lt;br /&gt;
&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=flowplayer Flowplayer HTML5] version 5.4.6.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=videojs Video.JS] version 4.4.1.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=projekktor Projekktor] version 1.3.09.&lt;br /&gt;
&lt;br /&gt;
=== Source ===&lt;br /&gt;
&lt;br /&gt;
Source of testing page is hosted on [https://github.com/kabalin/test-html5-players/blob/master/players.php github]. The actual source of the html page can be viewed in browser.&lt;br /&gt;
&lt;br /&gt;
=== Discussion ===&lt;br /&gt;
&lt;br /&gt;
The players comparison that has been carried out demonstrated that &amp;quot;least hassle&amp;quot; player is Flowplayer. Despite some drawbacks listed in corresponding section above, it is clearly a winner as it works as expected and according to documentation for all browsers and platforms I had chance to test it. This is the only player that supports RTL layout and was simple to configure (no undocumented tricks that I had to figure out to make it work). Both VideoJS and Projekktor do now perform properly in all cases. Among those two, I personally prefer Projekktor more for its extensive API, plugins infrastructure and configuration flexibility. However problems on mobile platforms and flash fallback inconsistency make them unreliable at this stage.  &lt;br /&gt;
&lt;br /&gt;
=== Compatibility results ===&lt;br /&gt;
&lt;br /&gt;
The table was populated using Flowplayer as others do not perform good enough with some formats and platforms, e.g. VideoJS allow mobile platform player to override itself, Projekktor does not always use HTML5 where browser clearly can handle it (supported in native mode and Flowplayer).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Browser&lt;br /&gt;
! mp4&lt;br /&gt;
! webm&lt;br /&gt;
! ogg&lt;br /&gt;
! flv&lt;br /&gt;
! RTMP/HLS*&lt;br /&gt;
|-&lt;br /&gt;
! Windows 7&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Firefox 27.0.1&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 12.16&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 5.1.7&lt;br /&gt;
| flash&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Internet Explorer 11.0.9600.x&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Linux (Debian Wheezy)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.115&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! OSX 10.9&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 7.0 (9537.71)&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 phone (CyanogenMod, no flash)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 tablet (GalaxyTab2, flash app 11.1.115.36)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 19.0.1340.x&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
! iPhone 4S (6.1.3)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! iPad 4 (7.0.6)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;small&amp;gt;* For HLS/RTMP, html5 in the table means HLS has been used, flash means player fell back and used RTMP.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sub Tasks ==&lt;br /&gt;
&lt;br /&gt;
== Mock-Ups/Prototypes ==&lt;br /&gt;
&lt;br /&gt;
== Related Tracker Issues ==&lt;br /&gt;
* MDL-38158&lt;br /&gt;
&lt;br /&gt;
== Useful links ==&lt;br /&gt;
* http://praegnanz.de/html5video/&lt;br /&gt;
* http://html5video.org/wiki/HTML5_Video_Player_Comparison&lt;br /&gt;
* http://www.streamingmedia.com/Articles/Editorial/Featured-Articles/Choosing-a-Video-Player-Features-and-Specs-for-the-Top-Five-94188.aspx&lt;br /&gt;
&lt;br /&gt;
[[Category:Project]]&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=44130</id>
		<title>HTML5 player</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=44130"/>
		<updated>2014-03-10T10:41:06Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: /* Cross-browser support checks */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}&lt;br /&gt;
{{Infobox Project&lt;br /&gt;
|name = HTML5 Player with flash fallback&lt;br /&gt;
|state = In Development&lt;br /&gt;
|tracker = https://tracker.moodle.org/browse/MDL-38158&lt;br /&gt;
|discussion = https://moodle.org/mod/forum/discuss.php?d=222753#p1105373&lt;br /&gt;
|assignee = [https://tracker.moodle.org/secure/ViewProfile.jspa?name=kabalin Ruslan Kabalin]&lt;br /&gt;
}}&lt;br /&gt;
{{Moodle 2.x}}&lt;br /&gt;
&lt;br /&gt;
== Project goals ==&lt;br /&gt;
&lt;br /&gt;
The purpose of this document is to choose HTML5 with flash fallback for integration in Moodle.&lt;br /&gt;
&lt;br /&gt;
The aim of this change is to reach a consistent look of the player among different platforms and browsers, as well as making sure that player starts using flash if html5 is not supported by browser for the given format. Another aim is to improve accessibility and usability, enhance customisation.&lt;br /&gt;
&lt;br /&gt;
== Considerations ==&lt;br /&gt;
&lt;br /&gt;
* Usability of the player - is it easy to use it and intuitively understand how to use controls?&lt;br /&gt;
* Accessibility of the player - possibility of keyboard navigation, subtitles, support?&lt;br /&gt;
* Appearance of the player - can its interface be modified, themes support, RTL?&lt;br /&gt;
* Consistency among browsers - does player look the same?&lt;br /&gt;
* Audio support - can player handle HTML5 &amp;lt;audio&amp;gt; tag?&lt;br /&gt;
* Mobile platforms support - does player also work on iOS and Android?&lt;br /&gt;
* Streaming media support (including adaptive-bitrate delivery) - can player handle RTMP, Apple HLS, Adobe HDS, Microsoft HSS?&lt;br /&gt;
* Plugins support - can we use or develop community plugins easily?&lt;br /&gt;
* Embedding support - so users could post media content outside Moodle, if permitted.&lt;br /&gt;
* Maintainability of the links between the player and Moodle - how much work will we need to do every time we upgrade?&lt;br /&gt;
&lt;br /&gt;
== Candidates ==&lt;br /&gt;
&lt;br /&gt;
* [http://flowplayer.org/ Flowplayer HTML5]&lt;br /&gt;
* [http://www.videojs.com/ Video.JS]&lt;br /&gt;
* [http://www.projekktor.com/ Projekktor]&lt;br /&gt;
* ?Are there other alternatives?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Flowplayer HTML5&lt;br /&gt;
! Video.JS&lt;br /&gt;
! Projekktor&lt;br /&gt;
|-&lt;br /&gt;
! Accessible Player:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Keyboard control&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes (configurable)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Subtitles support&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via plugin)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Touch interface&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Appearance:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Skins&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* CSS customisation&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTL support&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
! Mobile platforms:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* iOS&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Android&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Streaming protocols:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTMP&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via playlist)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Adaptive HTTP&lt;br /&gt;
| HLS&lt;br /&gt;
| HLS (via plugin)&lt;br /&gt;
| HLS (via playlist)&lt;br /&gt;
|-&lt;br /&gt;
! Audio player&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Embedding support&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (configurable)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via addThis plugin)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via plugin)&lt;br /&gt;
|-&lt;br /&gt;
! License&lt;br /&gt;
| GPL v3 (with additional terms)&lt;br /&gt;
| Apache 2&lt;br /&gt;
| GPL v3&lt;br /&gt;
|-&lt;br /&gt;
! JS library&lt;br /&gt;
| jQuery&lt;br /&gt;
| -&lt;br /&gt;
| jQuery&lt;br /&gt;
|-&lt;br /&gt;
! Plugins infrastructure&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Flash fallback player&lt;br /&gt;
| Flowplayer Flash&lt;br /&gt;
| video-js flash&lt;br /&gt;
| StobeMediaPlayback (but can be jarisplayer or some other).&lt;br /&gt;
|-&lt;br /&gt;
! API&lt;br /&gt;
| Yes (plus window.flowplayer object)&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Flowplayer HTML5 ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* Good looking player, resembles existing flash flowplayer in Moodle (with &amp;quot;functional&amp;quot; skin)&lt;br /&gt;
* Extensive customisation (via CSS3 skins and configuration object)&lt;br /&gt;
* Streaming support (RTMP, HLS)&lt;br /&gt;
* Good accessibility features&lt;br /&gt;
* Configurable embedding functionality&lt;br /&gt;
* Existing flash flowplayer can be configured for fallback (the appearance of player will not be affected).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Require jQuery for functioning&lt;br /&gt;
* Flowplayer logo remains on screen&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using wrapper around &amp;lt;video&amp;gt;.&lt;br /&gt;
* width and height attributes in video tag are ignored, player size is configured via wrapper size only.&lt;br /&gt;
* RTMP server connection is configured via data-rtmp attribute in wrapper or player init config parameter, actual path the file specified in src attribute of source item.&lt;br /&gt;
* &amp;lt;source type=&amp;quot;video/flash&amp;quot;... dummy MIME type to force using plash player for whatever content.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Plugins infrastructure&lt;br /&gt;
* No audio support&lt;br /&gt;
&lt;br /&gt;
=== Video.JS ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Extensive API.&lt;br /&gt;
* No extra JS library needed.&lt;br /&gt;
* Many plugins.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* RTMP requires non-standard MIME.&lt;br /&gt;
* Android and iOS override Video.JS with own player, when not overridden, content is not playing.&lt;br /&gt;
* No RTL.&lt;br /&gt;
* HLS support via plugin (many files to include, external contributor see https://github.com/videojs/videojs-contrib-hls).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* RTMP server connection and path specified as single URI in src attribute of source item, &#039;&amp;amp;&#039; character is used as server connection and path divider.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Embedded HLS support.&lt;br /&gt;
&lt;br /&gt;
=== Projekktor ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Well documented API.&lt;br /&gt;
* Media RSS support.&lt;br /&gt;
* Possibility to choose flash player for fallback (included by default are StrobeMediaPlayback and Jarisplayer, both Open Source).&lt;br /&gt;
* Platform preference order selection (e.g. browser, ios, android, flash, native).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Uses flash where it is not supposed to (e.g. mp4 in Chrome).&lt;br /&gt;
* Issues on ios (suggests to download file when play button is pressed).&lt;br /&gt;
* RTMP only work if defined via playlist rather than in &amp;lt;source&amp;gt; tags.&lt;br /&gt;
* Subtitles plugin is not free.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* Make sure &amp;lt;video&amp;gt; tag has class attribute with &#039;projekktor&#039; value (even if you initialise it by ID of the element), player will not work properly otherwise.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Cross-browser support ==&lt;br /&gt;
&lt;br /&gt;
=== Method ===&lt;br /&gt;
Compatibility checks were done manually by accessing the sample page using different browsers and platforms. Sample page contained the list of identical player instances, initialised for each &amp;lt;video&amp;gt; definition with a &amp;lt;source&amp;gt; of particular format: mp4, webm, ogg, flv. Streaming support was checked by setting up a &amp;lt;video&amp;gt; container with two sources of the same video, one was HLS (Apple HTTP Live Streaming) stream for browsers and platforms that support html5 video streaming, another one was RTMP which is played using flash engine and supposed to be used in case if HLS is not supported.&lt;br /&gt;
&lt;br /&gt;
=== Sample Pages ===&lt;br /&gt;
&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=flowplayer Flowplayer HTML5] version 5.4.6.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=videojs Video.JS] version 4.4.1.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=projekktor Projekktor] version 1.3.09.&lt;br /&gt;
&lt;br /&gt;
=== Source ===&lt;br /&gt;
&lt;br /&gt;
Source of testing page is hosted on [https://github.com/kabalin/test-html5-players/blob/master/players.php github]. The actual source of the html page can be viewed in browser.&lt;br /&gt;
&lt;br /&gt;
=== Discussion ===&lt;br /&gt;
&lt;br /&gt;
The players comparison that has been carried out demonstrated that &amp;quot;least hassle&amp;quot; player is Flowplayer. Despite some drawbacks listed in corresponding section above, it is clearly a winner as it works as expected and according to documentation for all browsers and platforms I had chance to test it. This is the only player that supports RTL layout and was simple to configure (no undocumented tricks that I had to figure out to make it work). Both VideoJS and Projekktor do now perform properly in all cases. Among those two, I personally prefer Projekktor more for its extensive API, plugins infrastructure and configuration flexibility. However problems on mobile platforms and flash fallback inconsistency make them unreliable at this stage.  &lt;br /&gt;
&lt;br /&gt;
=== Compatibility results ===&lt;br /&gt;
&lt;br /&gt;
The table was populated using Flowplayer as others do not perform good enough with some formats and platforms, e.g. VideoJS allow mobile platform player to override itself, Projekktor does not always use HTML5 where browser clearly can handle it (supported in native mode and Flowplayer).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Browser&lt;br /&gt;
! mp4&lt;br /&gt;
! webm&lt;br /&gt;
! ogg&lt;br /&gt;
! flv&lt;br /&gt;
! RTMP/HLS*&lt;br /&gt;
|-&lt;br /&gt;
! Windows 7&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Firefox 27.0.1&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 12.16&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 5.1.7&lt;br /&gt;
| flash&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Internet Explorer 11.0.9600.x&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Linux (Debian Wheezy)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.115&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! OSX 10.9&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 7.0 (9537.71)&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 phone (CyanogenMod, no flash)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 tablet (GalaxyTab2, flash app 11.1.115.36)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 19.0.1340.x&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
! iPhone 4S (6.1.3)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! iPad 4 (7.0.6)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;small&amp;gt;* For HLS/RTMP, html5 in the table means HLS has been used, flash means player fell back and used RTMP.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sub Tasks ==&lt;br /&gt;
&lt;br /&gt;
== Mock-Ups/Prototypes ==&lt;br /&gt;
&lt;br /&gt;
== Related Tracker Issues ==&lt;br /&gt;
* MDL-38158&lt;br /&gt;
&lt;br /&gt;
== Useful links ==&lt;br /&gt;
* http://praegnanz.de/html5video/&lt;br /&gt;
* http://html5video.org/wiki/HTML5_Video_Player_Comparison&lt;br /&gt;
* http://www.streamingmedia.com/Articles/Editorial/Featured-Articles/Choosing-a-Video-Player-Features-and-Specs-for-the-Top-Five-94188.aspx&lt;br /&gt;
&lt;br /&gt;
[[Category:Project]]&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=44129</id>
		<title>HTML5 player</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=HTML5_player&amp;diff=44129"/>
		<updated>2014-03-10T10:25:34Z</updated>

		<summary type="html">&lt;p&gt;Kabalin: /* Projekktor */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Work in progress}}&lt;br /&gt;
{{Infobox Project&lt;br /&gt;
|name = HTML5 Player with flash fallback&lt;br /&gt;
|state = In Development&lt;br /&gt;
|tracker = https://tracker.moodle.org/browse/MDL-38158&lt;br /&gt;
|discussion = https://moodle.org/mod/forum/discuss.php?d=222753#p1105373&lt;br /&gt;
|assignee = [https://tracker.moodle.org/secure/ViewProfile.jspa?name=kabalin Ruslan Kabalin]&lt;br /&gt;
}}&lt;br /&gt;
{{Moodle 2.x}}&lt;br /&gt;
&lt;br /&gt;
== Project goals ==&lt;br /&gt;
&lt;br /&gt;
The purpose of this document is to choose HTML5 with flash fallback for integration in Moodle.&lt;br /&gt;
&lt;br /&gt;
The aim of this change is to reach a consistent look of the player among different platforms and browsers, as well as making sure that player starts using flash if html5 is not supported by browser for the given format. Another aim is to improve accessibility and usability, enhance customisation.&lt;br /&gt;
&lt;br /&gt;
== Considerations ==&lt;br /&gt;
&lt;br /&gt;
* Usability of the player - is it easy to use it and intuitively understand how to use controls?&lt;br /&gt;
* Accessibility of the player - possibility of keyboard navigation, subtitles, support?&lt;br /&gt;
* Appearance of the player - can its interface be modified, themes support, RTL?&lt;br /&gt;
* Consistency among browsers - does player look the same?&lt;br /&gt;
* Audio support - can player handle HTML5 &amp;lt;audio&amp;gt; tag?&lt;br /&gt;
* Mobile platforms support - does player also work on iOS and Android?&lt;br /&gt;
* Streaming media support (including adaptive-bitrate delivery) - can player handle RTMP, Apple HLS, Adobe HDS, Microsoft HSS?&lt;br /&gt;
* Plugins support - can we use or develop community plugins easily?&lt;br /&gt;
* Embedding support - so users could post media content outside Moodle, if permitted.&lt;br /&gt;
* Maintainability of the links between the player and Moodle - how much work will we need to do every time we upgrade?&lt;br /&gt;
&lt;br /&gt;
== Candidates ==&lt;br /&gt;
&lt;br /&gt;
* [http://flowplayer.org/ Flowplayer HTML5]&lt;br /&gt;
* [http://www.videojs.com/ Video.JS]&lt;br /&gt;
* [http://www.projekktor.com/ Projekktor]&lt;br /&gt;
* ?Are there other alternatives?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Flowplayer HTML5&lt;br /&gt;
! Video.JS&lt;br /&gt;
! Projekktor&lt;br /&gt;
|-&lt;br /&gt;
! Accessible Player:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Keyboard control&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes (configurable)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Subtitles support&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via plugin)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Touch interface&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Appearance:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Skins&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
| Yes (via CSS)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* CSS customisation&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTL support&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
! Mobile platforms:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* iOS&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Android&lt;br /&gt;
| Yes&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Streaming protocols:&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* RTMP&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes (via playlist)&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Adaptive HTTP&lt;br /&gt;
| HLS&lt;br /&gt;
| HLS (via plugin)&lt;br /&gt;
| HLS (via playlist)&lt;br /&gt;
|-&lt;br /&gt;
! Audio player&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Embedding support&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (configurable)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via addThis plugin)&lt;br /&gt;
| style=&amp;quot;border-bottom: 2px solid;&amp;quot; | Yes (via plugin)&lt;br /&gt;
|-&lt;br /&gt;
! License&lt;br /&gt;
| GPL v3 (with additional terms)&lt;br /&gt;
| Apache 2&lt;br /&gt;
| GPL v3&lt;br /&gt;
|-&lt;br /&gt;
! JS library&lt;br /&gt;
| jQuery&lt;br /&gt;
| -&lt;br /&gt;
| jQuery&lt;br /&gt;
|-&lt;br /&gt;
! Plugins infrastructure&lt;br /&gt;
| No&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
! Flash fallback player&lt;br /&gt;
| Flowplayer Flash&lt;br /&gt;
| video-js flash&lt;br /&gt;
| StobeMediaPlayback (but can be jarisplayer or some other).&lt;br /&gt;
|-&lt;br /&gt;
! API&lt;br /&gt;
| Yes (plus window.flowplayer object)&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Flowplayer HTML5 ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* Good looking player, resembles existing flash flowplayer in Moodle (with &amp;quot;functional&amp;quot; skin)&lt;br /&gt;
* Extensive customisation (via CSS3 skins and configuration object)&lt;br /&gt;
* Streaming support (RTMP, HLS)&lt;br /&gt;
* Good accessibility features&lt;br /&gt;
* Configurable embedding functionality&lt;br /&gt;
* Existing flash flowplayer can be configured for fallback (the appearance of player will not be affected).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Require jQuery for functioning&lt;br /&gt;
* Flowplayer logo remains on screen&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using wrapper around &amp;lt;video&amp;gt;.&lt;br /&gt;
* width and height attributes in video tag are ignored, player size is configured via wrapper size only.&lt;br /&gt;
* RTMP server connection is configured via data-rtmp attribute in wrapper or player init config parameter, actual path the file specified in src attribute of source item.&lt;br /&gt;
* &amp;lt;source type=&amp;quot;video/flash&amp;quot;... dummy MIME type to force using plash player for whatever content.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Plugins infrastructure&lt;br /&gt;
* No audio support&lt;br /&gt;
&lt;br /&gt;
=== Video.JS ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Extensive API.&lt;br /&gt;
* No extra JS library needed.&lt;br /&gt;
* Many plugins.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* RTMP requires non-standard MIME.&lt;br /&gt;
* Android and iOS override Video.JS with own player, when not overridden, content is not playing.&lt;br /&gt;
* No RTL.&lt;br /&gt;
* HLS support via plugin (many files to include, external contributor see https://github.com/videojs/videojs-contrib-hls).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* RTMP server connection and path specified as single URI in src attribute of source item, &#039;&amp;amp;&#039; character is used as server connection and path divider.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
* Embedded HLS support.&lt;br /&gt;
&lt;br /&gt;
=== Projekktor ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros:&#039;&#039;&#039;&lt;br /&gt;
* No logo on screen.&lt;br /&gt;
* Well documented API.&lt;br /&gt;
* Media RSS support.&lt;br /&gt;
* Possibility to choose flash player for fallback (included by default are StrobeMediaPlayback and Jarisplayer, both Open Source).&lt;br /&gt;
* Platform preference order selection (e.g. browser, ios, android, flash, native).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
* Uses flash where it is not supposed to (e.g. mp4 in Chrome).&lt;br /&gt;
* Issues on ios (suggests to download file when play button is pressed).&lt;br /&gt;
* RTMP only work if defined via playlist rather than in &amp;lt;source&amp;gt; tags.&lt;br /&gt;
* Subtitles plugin is not free.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Technical notes (lessons learned from the prototypes)&#039;&#039;&#039;&lt;br /&gt;
* Player initialisation is done using &amp;lt;video&amp;gt; tag directly (no wrapper needed).&lt;br /&gt;
* Make sure &amp;lt;video&amp;gt; tag has class attribute with &#039;projekktor&#039; value (even if you initialise it by ID of the element), player will not work properly otherwise.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing features&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Cross-browser support checks ==&lt;br /&gt;
&lt;br /&gt;
=== Method ===&lt;br /&gt;
Compatibility checks were done manually by accessing the sample page using different browsers and platforms. Sample page contained the list of identical player instances, initialised for each &amp;lt;video&amp;gt; definition with a &amp;lt;source&amp;gt; of particular format: mp4, webm, ogg, flv. Streaming support was checked by setting up a &amp;lt;video&amp;gt; container with two sources of the same video, one was HLS (Apple HTTP Live Streaming) stream for browsers and platforms that support html5 video streaming, another one was RTMP which is played using flash engine and supposed to be used in case if HLS is not supported.&lt;br /&gt;
&lt;br /&gt;
=== Sample Pages ===&lt;br /&gt;
&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=flowplayer Flowplayer HTML5] version 5.4.6.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=videojs Video.JS] version 4.4.1.&lt;br /&gt;
* [https://dev.mle.lancs.ac.uk/videotest/players.php?player=projekktor Projekktor] version 1.3.09.&lt;br /&gt;
&lt;br /&gt;
=== Source ===&lt;br /&gt;
&lt;br /&gt;
Source of testing page is hosted on [https://github.com/kabalin/test-html5-players/blob/master/players.php github]. The actual source of the html page can be viewed in browser.&lt;br /&gt;
&lt;br /&gt;
=== Results ===&lt;br /&gt;
&lt;br /&gt;
The table was populated using Flowplayer as others do not perform good enough with some formats and platforms, e.g. VideoJS allow mobile platform player to override itself, Projekktor does not always use HTML5 where browser clearly can handle it (supported in native mode and Flowplayer).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Browser&lt;br /&gt;
! mp4&lt;br /&gt;
! webm&lt;br /&gt;
! ogg&lt;br /&gt;
! flv&lt;br /&gt;
! RTMP/HLS*&lt;br /&gt;
|-&lt;br /&gt;
! Windows 7&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Firefox 27.0.1&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 12.16&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 5.1.7&lt;br /&gt;
| flash&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Internet Explorer 11.0.9600.x&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Linux (Debian Wheezy)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.115&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! OSX 10.9&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari 7.0 (9537.71)&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 33.0.1750.117&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| flash&lt;br /&gt;
| flash&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 phone (CyanogenMod, no flash)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! Android 4.2.2 tablet (GalaxyTab2, flash app 11.1.115.36)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Chrome 32.0.1700.99&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Browser 4.2.2 (com.android.browser)&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| flash&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Opera 19.0.1340.x&lt;br /&gt;
| html5&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
! iPhone 4S (6.1.3)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
! iPad 4 (7.0.6)&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
* Safari&lt;br /&gt;
| html5&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| html5&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;small&amp;gt;* For HLS/RTMP, html5 in the table means HLS has been used, flash means player fell back and used RTMP.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sub Tasks ==&lt;br /&gt;
&lt;br /&gt;
== Mock-Ups/Prototypes ==&lt;br /&gt;
&lt;br /&gt;
== Related Tracker Issues ==&lt;br /&gt;
* MDL-38158&lt;br /&gt;
&lt;br /&gt;
== Useful links ==&lt;br /&gt;
* http://praegnanz.de/html5video/&lt;br /&gt;
* http://html5video.org/wiki/HTML5_Video_Player_Comparison&lt;br /&gt;
* http://www.streamingmedia.com/Articles/Editorial/Featured-Articles/Choosing-a-Video-Player-Features-and-Specs-for-the-Top-Five-94188.aspx&lt;br /&gt;
&lt;br /&gt;
[[Category:Project]]&lt;/div&gt;</summary>
		<author><name>Kabalin</name></author>
	</entry>
</feed>