├── LICENSE.md
├── flash
├── lib
│ ├── osmf
│ │ └── OSMF.swc
│ ├── jw5
│ │ └── jwplayer-5-lib.swc
│ └── jw6
│ │ └── jwplayer-6-lib.swc
├── src
│ ├── org
│ │ └── mangui
│ │ │ ├── jwplayer
│ │ │ └── media
│ │ │ │ ├── HLSProvider6.as
│ │ │ │ └── HLSProvider.as
│ │ │ ├── HLS
│ │ │ ├── HLSTypes.as
│ │ │ ├── HLSStates.as
│ │ │ ├── utils
│ │ │ │ └── Log.as
│ │ │ ├── parsing
│ │ │ │ ├── Fragment.as
│ │ │ │ ├── Manifest.as
│ │ │ │ └── Level.as
│ │ │ ├── muxing
│ │ │ │ ├── FLV.as
│ │ │ │ ├── PES.as
│ │ │ │ ├── Tag.as
│ │ │ │ ├── AAC.as
│ │ │ │ ├── AVC.as
│ │ │ │ └── TS.as
│ │ │ ├── HLSEvent.as
│ │ │ ├── HLS.as
│ │ │ └── streaming
│ │ │ │ ├── ManifestLoader.as
│ │ │ │ ├── HLSNetStream.as
│ │ │ │ └── FragmentLoader.as
│ │ │ └── osmf
│ │ │ └── plugins
│ │ │ ├── HLSTimeTrait.as
│ │ │ ├── HLSPlugin.as
│ │ │ ├── HLSNetLoader.as
│ │ │ └── HLSLoaderBase.as
│ ├── HLSOSMFDynamicPlugin.as
│ └── ChromelessPlayer.as
├── README.md
└── LICENSE.md
├── javascript
├── font
│ ├── self.eot
│ ├── self.ttf
│ ├── self.woff
│ ├── vjs.eot
│ ├── vjs.ttf
│ ├── vjs.woff
│ ├── self.svg
│ └── vjs.svg
├── LICENSE.md
├── ie9.css
└── ie8.css
└── README.markdown
/LICENSE.md:
--------------------------------------------------------------------------------
1 | see the flash and javascript directories for licenses
2 |
--------------------------------------------------------------------------------
/flash/lib/osmf/OSMF.swc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bjarnoldus/momovi-video-hls/HEAD/flash/lib/osmf/OSMF.swc
--------------------------------------------------------------------------------
/javascript/font/self.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bjarnoldus/momovi-video-hls/HEAD/javascript/font/self.eot
--------------------------------------------------------------------------------
/javascript/font/self.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bjarnoldus/momovi-video-hls/HEAD/javascript/font/self.ttf
--------------------------------------------------------------------------------
/javascript/font/self.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bjarnoldus/momovi-video-hls/HEAD/javascript/font/self.woff
--------------------------------------------------------------------------------
/javascript/font/vjs.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bjarnoldus/momovi-video-hls/HEAD/javascript/font/vjs.eot
--------------------------------------------------------------------------------
/javascript/font/vjs.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bjarnoldus/momovi-video-hls/HEAD/javascript/font/vjs.ttf
--------------------------------------------------------------------------------
/javascript/font/vjs.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bjarnoldus/momovi-video-hls/HEAD/javascript/font/vjs.woff
--------------------------------------------------------------------------------
/flash/lib/jw5/jwplayer-5-lib.swc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bjarnoldus/momovi-video-hls/HEAD/flash/lib/jw5/jwplayer-5-lib.swc
--------------------------------------------------------------------------------
/flash/lib/jw6/jwplayer-6-lib.swc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bjarnoldus/momovi-video-hls/HEAD/flash/lib/jw6/jwplayer-6-lib.swc
--------------------------------------------------------------------------------
/flash/src/org/mangui/jwplayer/media/HLSProvider6.as:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bjarnoldus/momovi-video-hls/HEAD/flash/src/org/mangui/jwplayer/media/HLSProvider6.as
--------------------------------------------------------------------------------
/flash/src/HLSOSMFDynamicPlugin.as:
--------------------------------------------------------------------------------
1 | package
2 | {
3 | import flash.display.Sprite;
4 | import flash.system.Security;
5 |
6 | import org.mangui.osmf.plugins.HLSPlugin;
7 | import org.osmf.media.PluginInfo;
8 |
9 | public class HLSOSMFDynamicPlugin extends Sprite
10 | {
11 | private var _pluginInfo:PluginInfo;
12 |
13 | public function HLSOSMFDynamicPlugin()
14 | {
15 | super();
16 | Security.allowDomain("*");
17 | _pluginInfo = new HLSPlugin();
18 | }
19 |
20 | public function get pluginInfo():PluginInfo{
21 | return _pluginInfo;
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/javascript/font/self.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/javascript/LICENSE.md:
--------------------------------------------------------------------------------
1 | design - Copyright 2014 momovi, momovi.com
2 | hls flash integration - Copyright 2014 momovi, momovi.com
3 | original videojs - Copyright 2013 Brightcove, Inc.
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
--------------------------------------------------------------------------------
/flash/src/org/mangui/HLS/HLSTypes.as:
--------------------------------------------------------------------------------
1 | //-------------------------------------------------------------------------------
2 | // Copyright (c) 2014-2013 NoZAP B.V.
3 | // Copyright (c) 2013 Guillaume du Pontavice (https://github.com/mangui/HLSprovider)
4 | //
5 | // This Source Code Form is subject to the terms of the Mozilla Public
6 | // License, v. 2.0. If a copy of the MPL was not distributed with this
7 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 | //
9 | // Authors:
10 | // Jeroen Arnoldus
11 | // Guillaume du Pontavice
12 | //-------------------------------------------------------------------------------
13 |
14 | package org.mangui.HLS {
15 |
16 |
17 | /** Identifiers for the different stream types. **/
18 | public class HLSTypes {
19 |
20 |
21 | /** Identifier for live events. **/
22 | public static const LIVE:String = "LIVE";
23 | /** Identifier for on demand clips. **/
24 | public static const VOD:String = "VOD";
25 |
26 |
27 | }
28 |
29 |
30 | }
--------------------------------------------------------------------------------
/flash/src/org/mangui/HLS/HLSStates.as:
--------------------------------------------------------------------------------
1 | //-------------------------------------------------------------------------------
2 | // Copyright (c) 2014-2013 NoZAP B.V.
3 | // Copyright (c) 2013 Guillaume du Pontavice (https://github.com/mangui/HLSprovider)
4 | //
5 | // This Source Code Form is subject to the terms of the Mozilla Public
6 | // License, v. 2.0. If a copy of the MPL was not distributed with this
7 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 | //
9 | // Authors:
10 | // Jeroen Arnoldus
11 | // Guillaume du Pontavice
12 | //-------------------------------------------------------------------------------
13 |
14 | package org.mangui.HLS {
15 |
16 |
17 | /** Identifiers for the different playback states. **/
18 | public class HLSStates {
19 |
20 |
21 | /** Identifiers for the idle state. **/
22 | public static const IDLE:String = "IDLE";
23 | /** Identifier for the buffering state. **/
24 | public static const BUFFERING:String = "BUFFERING";
25 | /** Identifier for the playing state. **/
26 | public static const PLAYING:String = "PLAYING";
27 | /** Identifier for the paused state. **/
28 | public static const PAUSED:String = "PAUSED";
29 |
30 |
31 | }
32 |
33 |
34 | }
--------------------------------------------------------------------------------
/flash/src/org/mangui/HLS/utils/Log.as:
--------------------------------------------------------------------------------
1 | //-------------------------------------------------------------------------------
2 | // Copyright (c) 2014-2013 NoZAP B.V.
3 | // Copyright (c) 2013 Guillaume du Pontavice (https://github.com/mangui/HLSprovider)
4 | //
5 | // This Source Code Form is subject to the terms of the Mozilla Public
6 | // License, v. 2.0. If a copy of the MPL was not distributed with this
7 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 | //
9 | // Authors:
10 | // Jeroen Arnoldus
11 | // Guillaume du Pontavice
12 | //-------------------------------------------------------------------------------
13 |
14 | package org.mangui.HLS.utils {
15 |
16 |
17 | import flash.external.ExternalInterface;
18 |
19 |
20 | /** Class that sends log messages to browser console. **/
21 | public class Log {
22 |
23 |
24 | public static var LOGGING:Boolean = true;
25 |
26 |
27 | /** Log a message to the console. **/
28 | public static function txt(message:*):void {
29 | if(LOGGING){
30 | if(ExternalInterface.available)
31 | ExternalInterface.call('console.log',String(message));
32 | else trace(message);
33 | }
34 | };
35 |
36 |
37 | };
38 |
39 |
40 | }
--------------------------------------------------------------------------------
/flash/src/org/mangui/osmf/plugins/HLSTimeTrait.as:
--------------------------------------------------------------------------------
1 | //-------------------------------------------------------------------------------
2 | // Copyright (c) 2014-2013 NoZAP B.V.
3 | // Copyright (c) 2013 Guillaume du Pontavice (https://github.com/mangui/HLSprovider)
4 | //
5 | // This Source Code Form is subject to the terms of the Mozilla Public
6 | // License, v. 2.0. If a copy of the MPL was not distributed with this
7 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 | //
9 | // Authors:
10 | // Jeroen Arnoldus
11 | // Guillaume du Pontavice
12 | //-------------------------------------------------------------------------------
13 |
14 | package org.mangui.osmf.plugins
15 | {
16 | import org.osmf.traits.TimeTrait;
17 |
18 | import org.mangui.HLS.HLS;
19 | import org.mangui.HLS.HLSEvent;
20 | import org.mangui.HLS.utils.*;
21 |
22 | public class HLSTimeTrait extends TimeTrait
23 | {
24 | private var _hls:HLS;
25 | private var _duration:Number = 0;
26 | private var _position:Number = 0;
27 | public function HLSTimeTrait(hls:HLS,duration:Number=0)
28 | {
29 | super(duration);
30 | _duration = duration;
31 | _hls = hls;
32 | _hls.addEventListener(HLSEvent.MEDIA_TIME,_mediaTimeHandler);
33 | }
34 |
35 | override public function get duration():Number
36 | {
37 | return _duration;
38 | }
39 |
40 | override public function get currentTime():Number
41 | {
42 | //Log.txt("HLSTimeTrait:get currentTime:" + _position);
43 | return _position;
44 | }
45 |
46 | /** Update playback position/duration **/
47 | private function _mediaTimeHandler(event:HLSEvent):void {
48 | _position = event.mediatime.position;
49 | _duration = event.mediatime.duration;
50 | };
51 | }
52 | }
--------------------------------------------------------------------------------
/flash/src/org/mangui/osmf/plugins/HLSPlugin.as:
--------------------------------------------------------------------------------
1 | //-------------------------------------------------------------------------------
2 | // Copyright (c) 2014-2013 NoZAP B.V.
3 | // Copyright (c) 2013 Guillaume du Pontavice (https://github.com/mangui/HLSprovider)
4 | //
5 | // This Source Code Form is subject to the terms of the Mozilla Public
6 | // License, v. 2.0. If a copy of the MPL was not distributed with this
7 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 | //
9 | // Authors:
10 | // Jeroen Arnoldus
11 | // Guillaume du Pontavice
12 | //-------------------------------------------------------------------------------
13 |
14 | package org.mangui.osmf.plugins
15 | {
16 | import org.osmf.elements.LoadFromDocumentElement;
17 | import org.osmf.media.MediaElement;
18 | import org.osmf.media.MediaFactoryItem;
19 | import org.osmf.media.MediaFactoryItemType;
20 | import org.osmf.media.MediaResourceBase;
21 | import org.osmf.media.PluginInfo;
22 | import org.osmf.media.URLResource;
23 |
24 | public class HLSPlugin extends PluginInfo
25 | {
26 | public function HLSPlugin(items:Vector.=null, elementCreationNotifFunc:Function=null){
27 |
28 | items = new Vector.();
29 | items.push(
30 | new MediaFactoryItem(
31 | 'org.mangui.osmf.plugins.HLSPlugin',
32 | canHandleResource,
33 | createMediaElement,
34 | MediaFactoryItemType.STANDARD
35 | )
36 | );
37 |
38 | super(items, elementCreationNotifFunc);
39 | }
40 |
41 | private function canHandleResource(resource:MediaResourceBase):Boolean{
42 | return HLSLoaderBase.canHandle(resource);
43 | }
44 |
45 | private function createMediaElement():MediaElement{
46 | return new LoadFromDocumentElement(null, new HLSLoaderBase());
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/javascript/ie9.css:
--------------------------------------------------------------------------------
1 | /*-------------------------------------------------------------------------------
2 | Copyright (c) 2014 wecast.it groep B.V.
3 |
4 | Licensed to the Apache Software Foundation (ASF) under one
5 | or more contributor license agreements. See the NOTICE file
6 | distributed with this work for additional information
7 | regarding copyright ownership. The ASF licenses this file
8 | to you under the Apache License, Version 2.0 (the
9 | "License"); you may not use this file except in compliance
10 | with the License. You may obtain a copy of the License at
11 |
12 | http://www.apache.org/licenses/LICENSE-2.0
13 |
14 | Unless required by applicable law or agreed to in writing,
15 | software distributed under the License is distributed on an
16 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 | KIND, either express or implied. See the License for the
18 | specific language governing permissions and limitations
19 | under the License.
20 |
21 | Authors:
22 | John Davies
23 |
24 | --------------------------------------------------------------------------------*/
25 |
26 | .vjs-default-skin .vjs-fullscreen-control:before {
27 | content: "\e000";
28 | margin-left: 5px;
29 | font-size: 14px;
30 | line-height: 3;
31 | top: -3px;
32 | }
33 |
34 | .vjs-default-skin .vjs-seek-handle:before {
35 | top: -7px;
36 | left: -0.2em;
37 | }
38 |
39 | .vjs-default-skin .vjs-volume-handle:before {
40 | top: -5px;
41 | left: -0.5em;
42 | }
43 |
44 | .modal {
45 | display: block;
46 | position: fixed;
47 | top: 0;
48 | bottom: 0;
49 | left: 0;
50 | right: 0;
51 | margin: 0;
52 | background: #000;
53 | padding: 20px;
54 | z-index: 950;
55 | }
56 |
57 |
58 | .down-select {
59 | color: #fff;
60 | }
61 |
62 | .down-select:focus {
63 | color: #fff;
64 | }
65 |
66 | .down-select option {
67 | color: #fff;
68 | background: #000;
69 | }
--------------------------------------------------------------------------------
/flash/src/org/mangui/HLS/parsing/Fragment.as:
--------------------------------------------------------------------------------
1 | //-------------------------------------------------------------------------------
2 | // Copyright (c) 2014-2013 NoZAP B.V.
3 | // Copyright (c) 2013 Guillaume du Pontavice (https://github.com/mangui/HLSprovider)
4 | //
5 | // This Source Code Form is subject to the terms of the Mozilla Public
6 | // License, v. 2.0. If a copy of the MPL was not distributed with this
7 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 | //
9 | // Authors:
10 | // Jeroen Arnoldus
11 | // Guillaume du Pontavice
12 | //-------------------------------------------------------------------------------
13 |
14 | package org.mangui.HLS.parsing {
15 |
16 |
17 | /** HLS streaming chunk. **/
18 | public class Fragment {
19 |
20 |
21 | /** Duration of this chunk. **/
22 | public var duration:Number;
23 | /** Start time of this chunk. **/
24 | public var start_time:Number;
25 | /** Start PTS of this chunk. **/
26 | public var start_pts:Number;
27 | /** computed Start PTS of this chunk. **/
28 | public var start_pts_computed:Number;
29 | /** sequence number of this chunk. **/
30 | public var seqnum:Number;
31 | /** URL to this chunk. **/
32 | public var url:String;
33 | /** continuity index of this chunk. **/
34 | public var continuity:Number;
35 |
36 |
37 |
38 | /** Create the fragment. **/
39 | public function Fragment(url:String, duration:Number, seqnum:Number,start_time:Number,continuity:Number):void {
40 | this.duration = duration;
41 | this.url = url;
42 | this.seqnum = seqnum;
43 | this.start_time = start_time;
44 | this.continuity = continuity;
45 | this.start_pts = Number.NEGATIVE_INFINITY;
46 | this.start_pts_computed = Number.NEGATIVE_INFINITY;
47 | };
48 | }
49 |
50 |
51 | }
--------------------------------------------------------------------------------
/javascript/ie8.css:
--------------------------------------------------------------------------------
1 | /*-------------------------------------------------------------------------------
2 | Copyright (c) 2014 wecast.it groep B.V.
3 |
4 | Licensed to the Apache Software Foundation (ASF) under one
5 | or more contributor license agreements. See the NOTICE file
6 | distributed with this work for additional information
7 | regarding copyright ownership. The ASF licenses this file
8 | to you under the Apache License, Version 2.0 (the
9 | "License"); you may not use this file except in compliance
10 | with the License. You may obtain a copy of the License at
11 |
12 | http://www.apache.org/licenses/LICENSE-2.0
13 |
14 | Unless required by applicable law or agreed to in writing,
15 | software distributed under the License is distributed on an
16 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 | KIND, either express or implied. See the License for the
18 | specific language governing permissions and limitations
19 | under the License.
20 |
21 | Authors:
22 | John Davies
23 |
24 | --------------------------------------------------------------------------------*/
25 |
26 |
27 | .vjs-default-skin .vjs-fullscreen-control:before {
28 | content: "\e000";
29 | margin-left: 5px;
30 | font-size: 14px;
31 | line-height: 3;
32 | top: -3px;
33 | }
34 |
35 | .vjs-default-skin .vjs-seek-handle:before {
36 | top: -9px;
37 | left: -0.2em;
38 | }
39 |
40 | .vjs-default-skin .vjs-volume-handle:before {
41 | top: -7px;
42 | left: -0.5em;
43 | }
44 |
45 | .modal {
46 | display: block;
47 | position: fixed;
48 | top: 0;
49 | bottom: 0;
50 | left: 0;
51 | right: 0;
52 | margin: 0;
53 | background: #000;
54 | padding: 20px;
55 | z-index: 950;
56 | }
57 |
58 |
59 | .down-select {
60 | color: #fff;
61 | }
62 |
63 | .down-select:focus {
64 | color: #fff;
65 | }
66 |
67 | .down-select option {
68 | color: #fff;
69 | background: #000;
70 | }
--------------------------------------------------------------------------------
/flash/src/org/mangui/osmf/plugins/HLSNetLoader.as:
--------------------------------------------------------------------------------
1 | //-------------------------------------------------------------------------------
2 | // Copyright (c) 2014-2013 NoZAP B.V.
3 | // Copyright (c) 2013 Guillaume du Pontavice (https://github.com/mangui/HLSprovider)
4 | //
5 | // This Source Code Form is subject to the terms of the Mozilla Public
6 | // License, v. 2.0. If a copy of the MPL was not distributed with this
7 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 | //
9 | // Authors:
10 | // Jeroen Arnoldus
11 | // Guillaume du Pontavice
12 | //-------------------------------------------------------------------------------
13 |
14 | package org.mangui.osmf.plugins
15 | {
16 | import flash.net.NetConnection;
17 | import flash.net.NetStream;
18 | import org.osmf.media.MediaResourceBase;
19 | import org.osmf.media.URLResource;
20 | import org.osmf.net.NetStreamLoadTrait;
21 | import org.osmf.net.httpstreaming.HTTPStreamingNetLoader;
22 | import org.osmf.traits.LoadState;
23 |
24 | import org.mangui.HLS.HLS;
25 | import org.mangui.HLS.utils.*;
26 |
27 | public class HLSNetLoader extends HTTPStreamingNetLoader
28 | {
29 |
30 | private var _duration:Number;
31 | private var _hls:HLS;
32 |
33 | public function HLSNetLoader(hls:HLS,duration:Number){
34 | _hls = hls;
35 | _duration = duration;
36 | super();
37 | }
38 |
39 | override public function canHandleResource(resource:MediaResourceBase):Boolean
40 | {
41 | return true;
42 | }
43 |
44 | override protected function createNetStream(connection:NetConnection, resource:URLResource):NetStream
45 | {
46 | return _hls.stream;
47 | }
48 |
49 | override protected function processFinishLoading(loadTrait:NetStreamLoadTrait):void
50 | {
51 | var resource:URLResource = loadTrait.resource as URLResource;
52 | loadTrait.setTrait(new HLSTimeTrait(_hls,_duration));
53 | updateLoadTrait(loadTrait, LoadState.READY);
54 | return;
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/README.markdown:
--------------------------------------------------------------------------------
1 | # Momovi.com HTML5 HLS video player
2 |
3 | The [momovi.com video hls player](https://momovi.com/opensource/momovi-video-hls) is a free to use, open source HTML5 HLS video player.
4 | Supported platforms:
5 | - all major browsers, including Safari, Chrome, FireFox, Internet Explorer;
6 | - Tablets, including iPad and Android 4.2+
7 | - Smart phones, including iPhone, Android 4.2+ and Black Berry.
8 |
9 | ## Usage
10 | - Download the video player from [momovi.com video hls player](https://momovi.com/opensource/momovi-video-hls)
11 | - Unzip, extract and upload the content to your server
12 | - Configure the HTML to your needs
13 |
14 | ## Features
15 |
16 | - VoD & Live playlists
17 | - Adaptive streaming
18 | - Discontinuity support of video tracks
19 | - Supported by major desktop browsers, iOS, black berry and android
20 | - Configurable seeking method on VoD
21 | - Accurate seeking to exact requested position
22 | - Key frame based seeking (nearest key frame)
23 | - Segment based seeking (beginning of segment)
24 | - AES-128 decryption
25 | - Buffer progress report
26 | - Error resilience
27 | - Retry mechanism on I/O errors
28 | - Recovery mechanism on badly segmented TS streams
29 |
30 | ### Supported M3U8 tags
31 |
32 | - `#EXTM3U`
33 | - `#EXTINF`
34 | - `#EXT-X-STREAM-INF` (Multiple bitrate)
35 | - `#EXT-X-ENDLIST` (VoD / Live playlist)
36 | - `#EXT-X-MEDIA-SEQUENCE`
37 | - `#EXT-X-TARGETDURATION`
38 | - `#EXT-X-DISCONTINUITY` (VoD and Live playlist)
39 | - `#EXT-X-DISCONTINUITY-SEQUENCE` (VoD and Live playlist)
40 | - `#EXT-X-PROGRAM-DATE-TIME` (optional, used to synchronize time-stamps and sequence number when switching from one level to another)
41 | - `#EXT-X-KEY` (AES-128 method supported only)
42 | - `#EXT-X-BYTERANGE`
43 |
44 |
45 |
46 | ## Contributing
47 | The momovi.com video player is a free and open source library, and we appreciate any help you're willing to give. Contact us for bugs, feature requests and other questions at opensource@ .
48 |
49 | ## License
50 | The momovi.com video player is based on two open source projects, released under different licences
51 |
52 | - HTML5 video player:
53 | - hls flash integration - Copyright 2014-2015 Momovi.com, The Netherlands
54 | - original videojs - Copyright 2013 Brightcove, Inc.
55 |
56 | - HLS Flash player plugin:
57 | - discontinuity tag - Jeroen Arnoldus Copyright (c) 2014
58 | - original - Copyright (c) 2013 Guillaume du Pontavice (https://github.com/mangui/flashls)
59 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/flash/src/org/mangui/HLS/muxing/FLV.as:
--------------------------------------------------------------------------------
1 | //-------------------------------------------------------------------------------
2 | // Copyright (c) 2014-2013 NoZAP B.V.
3 | // Copyright (c) 2013 Guillaume du Pontavice (https://github.com/mangui/HLSprovider)
4 | //
5 | // This Source Code Form is subject to the terms of the Mozilla Public
6 | // License, v. 2.0. If a copy of the MPL was not distributed with this
7 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 | //
9 | // Authors:
10 | // Jeroen Arnoldus
11 | // Guillaume du Pontavice
12 | //-------------------------------------------------------------------------------
13 |
14 | package org.mangui.HLS.muxing {
15 |
16 |
17 | import flash.utils.ByteArray;
18 |
19 |
20 | /** Helpers for the FLV file format. **/
21 | public class FLV {
22 |
23 |
24 | /** Return an EOS Video tag (16 bytes). **/
25 | public static function getEosTag(stamp:Number):ByteArray {
26 | var tag:ByteArray = FLV.getTagHeader(false,5,stamp);
27 | // AVC Keyframe.
28 | tag.writeByte(0x17);
29 | // Sequence end, composition time
30 | tag.writeUnsignedInt(0x02000000);
31 | return tag;
32 | };
33 |
34 |
35 | /** Get the FLV file header. **/
36 | public static function getHeader():ByteArray {
37 | var flv:ByteArray = new ByteArray();
38 | // "F" + "L" + "V".
39 | flv.writeByte(0x46);
40 | flv.writeByte(0x4C);
41 | flv.writeByte(0x56);
42 | // File version (1)
43 | flv.writeByte(1);
44 | // Audio + Video tags.
45 | flv.writeByte(1);
46 | // Length of the header.
47 | flv.writeUnsignedInt(9);
48 | // PreviousTagSize0
49 | flv.writeUnsignedInt(0);
50 | return flv;
51 | };
52 |
53 |
54 | /** Get an FLV Tag header (11 bytes). **/
55 | public static function getTagHeader(audio:Boolean,length:Number,stamp:Number):ByteArray {
56 | var tag:ByteArray = new ByteArray();
57 | // Audio (8) or Video (9) tag
58 | if(audio) {
59 | tag.writeByte(8);
60 | } else {
61 | tag.writeByte(9);
62 | }
63 | // Size of the tag in bytes after StreamID.
64 | tag.writeByte(length >> 16);
65 | tag.writeByte(length >> 8);
66 | tag.writeByte(length);
67 | // Timestamp (lower 24 plus upper 8)
68 | tag.writeByte(stamp >> 16);
69 | tag.writeByte(stamp >> 8);
70 | tag.writeByte(stamp);
71 | tag.writeByte(stamp >> 24);
72 | // StreamID (3 empty bytes)
73 | tag.writeByte(0);
74 | tag.writeByte(0);
75 | tag.writeByte(0);
76 | // All done
77 | return tag;
78 | };
79 |
80 |
81 | }
82 |
83 |
84 | }
--------------------------------------------------------------------------------
/flash/src/org/mangui/HLS/muxing/PES.as:
--------------------------------------------------------------------------------
1 | //-------------------------------------------------------------------------------
2 | // Copyright (c) 2014-2013 NoZAP B.V.
3 | // Copyright (c) 2013 Guillaume du Pontavice (https://github.com/mangui/HLSprovider)
4 | //
5 | // This Source Code Form is subject to the terms of the Mozilla Public
6 | // License, v. 2.0. If a copy of the MPL was not distributed with this
7 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 | //
9 | // Authors:
10 | // Jeroen Arnoldus
11 | // Guillaume du Pontavice
12 | //-------------------------------------------------------------------------------
13 |
14 | package org.mangui.HLS.muxing {
15 |
16 |
17 | import org.mangui.HLS.muxing.*;
18 | import org.mangui.HLS.utils.*;
19 | import flash.utils.ByteArray;
20 |
21 |
22 | /** Representation of a Packetized Elementary Stream. **/
23 | public class PES {
24 |
25 |
26 | /** Timescale of pts/dts is 90khz. **/
27 | public static var TIMESCALE:Number = 90;
28 |
29 |
30 | /** Is it AAC audio or AVC video. **/
31 | public var audio:Boolean;
32 | /** The PES data (including headers). **/
33 | public var data:ByteArray;
34 | /** Start of the payload. **/
35 | public var payload:Number;
36 | /** Timestamp from the PTS header. **/
37 | public var pts:Number;
38 | /** Timestamp from the DTS header. **/
39 | public var dts:Number;
40 |
41 |
42 | /** Save the first chunk of PES data. **/
43 | public function PES(dat:ByteArray,aud:Boolean) {
44 | data = dat;
45 | audio = aud;
46 | };
47 |
48 |
49 | /** Append PES data from additional TS packets. **/
50 | public function append(dat:ByteArray):void {
51 | data.writeBytes(dat,0,0);
52 | };
53 |
54 |
55 | /** When all data is appended, parse the PES headers. **/
56 | public function parse():void {
57 | data.position = 0;
58 | // Start code prefix and packet ID.
59 | var prefix:Number = data.readUnsignedInt();
60 | /*Audio streams (0x1C0-0x1DF)
61 | Video streams (0x1E0-0x1EF)
62 | 0x1BD is special case, could be audio or video (ffmpeg\libavformat\mpeg.c)
63 | */
64 | if((audio && (prefix > 0x1df || prefix < 0x1c0 && prefix !=0x1bd)) ||
65 | (!audio && prefix != 0x1e0 && prefix != 0x1ea && prefix != 0x1bd)) {
66 | throw new Error("PES start code not found or not AAC/AVC: " + prefix);
67 | }
68 | // Ignore packet length and marker bits.
69 | data.position += 3;
70 | // Check for PTS
71 | var flags:uint = (data.readUnsignedByte() & 192) >> 6;
72 | if(flags != 2 && flags != 3) {
73 | throw new Error("No PTS/DTS in this PES packet");
74 | }
75 | // Check PES header length
76 | var length:uint = data.readUnsignedByte();
77 | // Grab the timestamp from PTS data (spread out over 5 bytes):
78 | // XXXX---X -------- -------X -------- -------X
79 |
80 | var _pts:Number = ((data.readUnsignedByte() & 0x0e) << 29) +
81 | ((data.readUnsignedShort() >> 1) << 15) +
82 | (data.readUnsignedShort() >> 1);
83 | length -= 5;
84 | var _dts:Number = _pts;
85 | if(flags == 3) {
86 | // Grab the DTS (like PTS)
87 | _dts = ((data.readUnsignedByte() & 0x0e) << 29) +
88 | ((data.readUnsignedShort() >> 1) << 15) +
89 | (data.readUnsignedShort() >> 1);
90 | length -= 5;
91 | }
92 | pts = Math.round(_pts / PES.TIMESCALE);
93 | dts = Math.round(_dts / PES.TIMESCALE);
94 | // Skip other header data and parse payload.
95 | data.position += length;
96 | payload = data.position;
97 | };
98 |
99 |
100 | }
101 |
102 |
103 | }
--------------------------------------------------------------------------------
/flash/src/org/mangui/HLS/HLSEvent.as:
--------------------------------------------------------------------------------
1 | //-------------------------------------------------------------------------------
2 | // Copyright (c) 2014-2013 NoZAP B.V.
3 | // Copyright (c) 2013 Guillaume du Pontavice (https://github.com/mangui/HLSprovider)
4 | //
5 | // This Source Code Form is subject to the terms of the Mozilla Public
6 | // License, v. 2.0. If a copy of the MPL was not distributed with this
7 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 | //
9 | // Authors:
10 | // Jeroen Arnoldus
11 | // Guillaume du Pontavice
12 | //-------------------------------------------------------------------------------
13 |
14 | package org.mangui.HLS {
15 |
16 |
17 | import flash.events.Event;
18 |
19 |
20 | /** Event fired when an error prevents playback. **/
21 | public class HLSEvent extends Event {
22 |
23 |
24 | /** Identifier for a playback complete event. **/
25 | public static const PLAYBACK_COMPLETE:String = "hlsEventPlayBackComplete";
26 | /** Identifier for a playback error event. **/
27 | public static const ERROR:String = "hlsEventError";
28 | /** Identifier for a fragment load event. **/
29 | public static const FRAGMENT_LOADED:String = "hlsEventFragmentLoaded";
30 | /** Identifier when last fragment of playlist has been loaded **/
31 | public static const LAST_VOD_FRAGMENT_LOADED:String = "hlsEventLastFragmentLoaded";
32 | /** Identifier for a manifest (re)load event. **/
33 | public static const MANIFEST_LOADED:String = "hlsEventManifest";
34 | /** Identifier for a playback media time change event. **/
35 | public static const MEDIA_TIME:String = "hlsEventMediaTime";
36 | /** Identifier for a playback state switch event. **/
37 | public static const STATE:String = "hlsEventState";
38 | /** Identifier for a quality level switch event. **/
39 | public static const QUALITY_SWITCH:String = "hlsEventQualitySwitch";
40 | /** Identifier for a level updated event (playlist loaded) **/
41 | public static const LEVEL_UPDATED:String = "hlsEventLevelUpdated";
42 | /** Identifier for a Level Time Stamp updated event (PTS updated) **/
43 | public static const LEVEL_PTS_UPDATED:String = "hlsEventLevelPTSUpdated";
44 | /** Identifier for a audio only fragment **/
45 | public static const AUDIO_ONLY:String = "audioOnly";
46 |
47 | /** The current quality level. **/
48 | public var level:Number;
49 | /** The list with quality levels. **/
50 | public var levels:Array;
51 | /** The error message. **/
52 | public var message:String;
53 | /** The current QOS metrics. **/
54 | public var metrics:Object;
55 | /** The time position. **/
56 | public var mediatime:Object;
57 | /** The new playback state. **/
58 | public var state:String;
59 |
60 |
61 | /** Assign event parameter and dispatch. **/
62 | public function HLSEvent(type:String, parameter:*=null) {
63 | switch(type) {
64 | case HLSEvent.ERROR:
65 | message = parameter as String;
66 | break;
67 | case HLSEvent.FRAGMENT_LOADED:
68 | metrics = parameter as Object;
69 | break;
70 | case HLSEvent.MANIFEST_LOADED:
71 | levels = parameter as Array;
72 | break;
73 | case HLSEvent.MEDIA_TIME:
74 | mediatime = parameter as Object;
75 | break;
76 | case HLSEvent.STATE:
77 | state = parameter as String;
78 | break;
79 | case HLSEvent.QUALITY_SWITCH:
80 | level = parameter as Number;
81 | break;
82 | case HLSEvent.LEVEL_UPDATED:
83 | level = parameter as Number;
84 | break;
85 | case HLSEvent.LEVEL_PTS_UPDATED:
86 | level = parameter as Number;
87 | break;
88 | }
89 | super(type, false, false);
90 | };
91 |
92 |
93 | }
94 |
95 |
96 | }
--------------------------------------------------------------------------------
/flash/src/org/mangui/HLS/HLS.as:
--------------------------------------------------------------------------------
1 | //-------------------------------------------------------------------------------
2 | // Copyright (c) 2014-2013 NoZAP B.V.
3 | // Copyright (c) 2013 Guillaume du Pontavice (https://github.com/mangui/HLSprovider)
4 | //
5 | // This Source Code Form is subject to the terms of the Mozilla Public
6 | // License, v. 2.0. If a copy of the MPL was not distributed with this
7 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 | //
9 | // Authors:
10 | // Jeroen Arnoldus
11 | // Guillaume du Pontavice
12 | //-------------------------------------------------------------------------------
13 |
14 | package org.mangui.HLS {
15 |
16 |
17 | import org.mangui.HLS.streaming.*;
18 | import org.mangui.HLS.utils.*;
19 |
20 | import flash.events.*;
21 | import flash.net.NetStream;
22 | import flash.net.NetConnection;
23 |
24 | /** Class that manages the streaming process. **/
25 | public class HLS extends EventDispatcher {
26 | /** The quality monitor. **/
27 | private var _fragmentLoader:FragmentLoader;
28 | /** The manifest parser. **/
29 | private var _manifestLoader:ManifestLoader;
30 | /** HLS NetStream **/
31 | private var _hlsNetStream:HLSNetStream;
32 |
33 | private var _client:Object = {};
34 |
35 | /** Create and connect all components. **/
36 | public function HLS():void {
37 | var connection:NetConnection = new NetConnection();
38 | connection.connect(null);
39 | _manifestLoader = new ManifestLoader(this);
40 | _fragmentLoader = new FragmentLoader(this);
41 | _hlsNetStream = new HLSNetStream(connection,this, _fragmentLoader);
42 | };
43 |
44 |
45 | /** Forward internal errors. **/
46 | override public function dispatchEvent(event:Event):Boolean {
47 | if(event.type == HLSEvent.ERROR) {
48 | Log.txt(HLSEvent(event).message);
49 | _hlsNetStream.close();
50 | }
51 | return super.dispatchEvent(event);
52 | };
53 |
54 |
55 | /** Return the current quality level. **/
56 | public function getLevel():Number {
57 | return _fragmentLoader.getLevel();
58 | };
59 |
60 |
61 | /** Return the list with bitrate levels. **/
62 | public function getLevels():Array {
63 | return _manifestLoader.getLevels();
64 | };
65 |
66 |
67 | /** Return the list with switching metrics. **/
68 | public function getMetrics():Object {
69 | return _fragmentLoader.getMetrics();
70 | };
71 |
72 |
73 | /** Return the current playback position. **/
74 | public function getPosition():Number {
75 | return _hlsNetStream.getPosition();
76 | };
77 |
78 |
79 | /** Return the current playback position. **/
80 | public function getState():String {
81 | return _hlsNetStream.getState();
82 | };
83 |
84 |
85 | /** Return the type of stream. **/
86 | public function getType():String {
87 | return _manifestLoader.getType();
88 | };
89 |
90 |
91 | /** Start playing an new HLS stream. **/
92 | public function play(url:String,start:Number=0):void {
93 | _hlsNetStream.close();
94 | //_playbackStartPosition = start;
95 | _manifestLoader.load(url);
96 | };
97 |
98 | /** Update the screen width. **/
99 | public function setWidth(width:Number):void {
100 | _fragmentLoader.setWidth(width);
101 | };
102 |
103 | /* update playback quality level */
104 | public function setPlaybackQuality(level:Number):void {
105 | _fragmentLoader.setPlaybackQuality(level);
106 | _hlsNetStream.seek(_hlsNetStream.getPosition());
107 | };
108 | public function get stream():NetStream {
109 | return _hlsNetStream;
110 | }
111 | public function get client():Object {
112 | return _client;
113 | }
114 | public function set client(value:Object):void {
115 | _client = value;
116 | }
117 | }
118 | ;
119 | }
--------------------------------------------------------------------------------
/flash/README.md:
--------------------------------------------------------------------------------
1 | #BUILD
2 |
3 | Unzip de zip in sdks to 4.6.0
4 | OS X issue: remove the -d32 option in $FLEXPATH/bin/mxmlc batch file of flash
5 |
6 | run the build.sh in builds
7 |
8 | The result is an OSMF player for StrobeMediaPlayback
9 |
10 | #PATCHES By momovi.com
11 |
12 | Now handles discontinuities in live streams automatically
13 |
14 | #TODO (but not really important)
15 | -Set player to Live or VOD (now hided in the webpage)
16 | -subtitles
17 | -test for multiple streams
18 |
19 |
20 | #HLSprovider
21 |
22 | **HLSProvider** is an AS3 plugin that allows you to play HLS playlist using either :
23 |
24 | * **Chromeless** Flash Player
25 | * **JWPlayer** Flash free edition version **5.x**
26 | * **JWPlayer** Flash free edition version **6.x**
27 | * **OSMF** version **2.0** (beta stage, any help welcomed !)
28 |
29 |
30 | **HLSProvider** supports the following features :
31 |
32 | * VOD/live/DVR playlists
33 | * multiple bitrate playlist / adaptive streaming
34 | * automatic quality switching, using serial segment fetching method described in [http://www.cs.tut.fi/%7Emoncef/publications/rate-adaptation-IC-2011.pdf](http://www.cs.tut.fi/%7Emoncef/publications/rate-adaptation-IC-2011.pdf)
35 | * manual quality switching (JWPlayer 6 only)
36 | * seeking in VoD and live playlist
37 | * buffer progress report
38 | * error resilience (retry mechanism in case of I/O Errors)
39 | * accurate seeking (seek to exact position,not to fragment boundary)
40 |
41 | the following M3U8 tags are supported:
42 |
43 | * #EXTM3U
44 | * #EXTINF
45 | * #EXT-X-STREAM-INF (used to support multiple bitrate)
46 | * #EXT-X-ENDLIST (supports live / event / VOD playlist)
47 | * #EXT-X-MEDIA-SEQUENCE (value is used for live playlist update)
48 | * #EXT-X-TARGETDURATION (value is used as live playlist reload interval)
49 | * #EXT-X-DISCONTINUITY
50 |
51 | ##HLSProvider in action :
52 |
53 | * http://streambox.fr/HLSProvider/chromeless
54 | * http://streambox.fr/HLSProvider/jwplayer5
55 | * http://streambox.fr/HLSProvider/jwplayer6
56 | * http://streambox.fr/HLSProvider/osmf
57 |
58 |
59 | ##How to use it :
60 |
61 | download package : https://github.com/mangui/HLSprovider/archive/master.zip
62 |
63 | ###jwplayer5 based setup:
64 | from zip, extract test/chromeless folder, and get inspired by example.html
65 |
66 | ###OSMF based setup:
67 | from zip, extract test/osmf folder, and get inspired by index.html
68 |
69 | ###jwplayer5 based setup:
70 | from zip, extract test/jwplayer5 folder, and get inspired by example.html
71 |
72 |
73 |
74 |
84 |
85 | ###jwplayer6 based setup:
86 | from zip, extract test/jwplayer6 folder, and get inspired by example.html
87 |
88 |
89 |
90 |