PageRenderTime 63ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 1ms

/public/vendor/npm/webshim@1.15.8/swfs/jaris/src/jaris/player/Player.hx

https://github.com/yeban/sequenceserver
Haxe | 1697 lines | 1075 code | 308 blank | 314 comment | 287 complexity | 5847ba22b0ddf404d57218d5e7c6edf4 MD5 | raw file
  1. /**
  2. * @author Jefferson González
  3. * @copyright 2010 Jefferson González
  4. *
  5. * @license
  6. * This file is part of Jaris FLV Player.
  7. *
  8. * Jaris FLV Player is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License or GNU LESSER GENERAL
  10. * PUBLIC LICENSE as published by the Free Software Foundation, either version
  11. * 3 of the License, or (at your option) any later version.
  12. *
  13. * Jaris FLV Player is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License and
  19. * GNU LESSER GENERAL PUBLIC LICENSE along with Jaris FLV Player. If not,
  20. * see <http://www.gnu.org/licenses/>.
  21. */
  22. package jaris.player;
  23. import flash.display.Loader;
  24. import flash.display.MovieClip;
  25. import flash.display.Sprite;
  26. import flash.display.Stage;
  27. import flash.display.BitmapData;
  28. import flash.display.JPEGEncoderOptions;
  29. import flash.utils.ByteArray;
  30. import flash.display.StageDisplayState;
  31. import flash.events.AsyncErrorEvent;
  32. import flash.events.Event;
  33. import flash.events.EventDispatcher;
  34. import flash.events.FullScreenEvent;
  35. import flash.events.IOErrorEvent;
  36. import flash.events.KeyboardEvent;
  37. import flash.events.MouseEvent;
  38. import flash.events.NetStatusEvent;
  39. import flash.events.ProgressEvent;
  40. import flash.events.TimerEvent;
  41. import flash.events.StatusEvent;
  42. import flash.geom.Rectangle;
  43. import flash.Lib;
  44. import flash.media.ID3Info;
  45. import flash.media.Sound;
  46. import flash.media.SoundChannel;
  47. import flash.media.SoundTransform;
  48. import flash.media.Video;
  49. import flash.media.Camera;
  50. import flash.net.NetConnection;
  51. import flash.net.NetStream;
  52. import flash.net.URLRequest;
  53. import flash.system.Capabilities;
  54. import flash.system.Security;
  55. import flash.system.SecurityPanel;
  56. import flash.ui.Keyboard;
  57. import flash.ui.Mouse;
  58. import flash.utils.Timer;
  59. import jaris.events.PlayerEvents;
  60. import jaris.utils.Utils;
  61. import jaris.player.AspectRatio;
  62. import jaris.player.UserSettings;
  63. import flash.errors.IOError;
  64. import flash.geom.Matrix;
  65. /**
  66. * Jaris main video player
  67. */
  68. class Player extends EventDispatcher {
  69. //{Member variables
  70. private var _stage:Stage;
  71. private var _movieClip:MovieClip;
  72. private var _connection:NetConnection;
  73. private var _stream:NetStream;
  74. private var _fullscreen:Bool;
  75. private var _soundMuted:Bool;
  76. private var _volume:Float;
  77. private var _bufferTime:Float;
  78. private var _mouseVisible:Bool;
  79. private var _mediaLoaded:Bool;
  80. private var _hideMouseTimer:Timer;
  81. private var _checkAudioTimer:Timer;
  82. private var _mediaSource:String;
  83. private var _type:String;
  84. private var _streamType:String;
  85. private var _server:String; //For future use on rtmp
  86. private var _sound:Sound;
  87. private var _soundChannel:SoundChannel;
  88. private var _id3Info:ID3Info;
  89. private var _video:Video;
  90. private var _videoWidth:Float;
  91. private var _videoHeight:Float;
  92. private var _scaleWidth:Int;
  93. private var _scaleHeight:Int;
  94. public var _naturalWidth:Float;
  95. public var _naturalHeight:Float;
  96. public var fullMetaData:Dynamic;
  97. private var _videoMask:Sprite;
  98. private var _videoQualityHigh:Bool;
  99. private var _mediaDuration:Float;
  100. private var _lastTime:Float;
  101. private var _lastProgress:Float;
  102. public var _isPlaying:Bool;
  103. private var _aspectRatio:Float;
  104. private var _currentAspectRatio:String;
  105. private var _originalAspectRatio:Float;
  106. private var _mediaEndReached:Bool;
  107. private var _seekPoints:Array<Float>;
  108. private var _downloadCompleted:Bool;
  109. private var _startTime:Float;
  110. private var _firstLoad:Bool;
  111. private var _stopped:Bool;
  112. private var _useHardWareScaling:Bool;
  113. private var _youtubeLoader:Loader;
  114. private var _userSettings:UserSettings;
  115. private var _loadedYoutube:Bool;
  116. private var _ytReady:Bool;
  117. private var _ytCue:Bool;
  118. public var noAPITrigger:Bool;
  119. public var _showLoader:Bool;
  120. private var _preLoading:Bool;
  121. private var _requestedPlay:Bool;
  122. private var _requestedLoad:Bool;
  123. private var _allowPreloadedPlay:Bool;
  124. private var _hasPoster:Bool;
  125. public var lastSeekTime:Float;
  126. private var _cam:Camera;
  127. public var camLength:Int;
  128. //}
  129. //{Constructor
  130. public function new() {
  131. super();
  132. //{Main Variables Init
  133. _stage = Lib.current.stage;
  134. _movieClip = Lib.current;
  135. _mouseVisible = true;
  136. _soundMuted = false;
  137. _volume = 1.0;
  138. _bufferTime = 10;
  139. _fullscreen = false;
  140. _mediaLoaded = false;
  141. _requestedLoad = false;
  142. _hideMouseTimer = new Timer(1500);
  143. _checkAudioTimer = new Timer(100);
  144. _seekPoints = new Array();
  145. _downloadCompleted = false;
  146. _startTime = 0;
  147. _firstLoad = true;
  148. _stopped = false;
  149. _videoQualityHigh = false;
  150. _loadedYoutube = false;
  151. _ytReady = false;
  152. _ytCue = false;
  153. _isPlaying = false;
  154. _streamType = StreamType.FILE;
  155. _type = InputType.VIDEO;
  156. _server = "";
  157. _currentAspectRatio = "original";
  158. _aspectRatio = 0;
  159. _lastTime = 0;
  160. _lastProgress = 0;
  161. _userSettings = new UserSettings();
  162. noAPITrigger = false;
  163. _hasPoster = false;
  164. _showLoader = true;
  165. lastSeekTime = 0;
  166. _allowPreloadedPlay = false;
  167. _naturalWidth = 0;
  168. _naturalHeight = 0;
  169. camLength = Camera.names.length;
  170. //}
  171. //{Initialize sound object
  172. _sound = new Sound();
  173. _sound.addEventListener(Event.COMPLETE, onSoundComplete);
  174. _sound.addEventListener(Event.ID3, onSoundID3);
  175. _sound.addEventListener(IOErrorEvent.IO_ERROR, onSoundIOError);
  176. _sound.addEventListener(ProgressEvent.PROGRESS, onSoundProgress);
  177. //}
  178. //{Initialize video and connection objects
  179. _connection = new NetConnection();
  180. _connection.client = this;
  181. _connection.connect(null);
  182. _stream = new NetStream(_connection);
  183. _video = new Video(_stage.stageWidth, _stage.stageHeight);
  184. _movieClip.addChild(_video);
  185. //}
  186. //Video mask so that custom menu items work
  187. _videoMask = new Sprite();
  188. _movieClip.addChild(_videoMask);
  189. //Set initial rendering to high quality
  190. toggleQuality();
  191. //{Initialize system event listeners
  192. _movieClip.addEventListener(Event.ENTER_FRAME, onEnterFrame);
  193. _stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
  194. _stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
  195. _stage.addEventListener(FullScreenEvent.FULL_SCREEN, onFullScreen);
  196. _stage.addEventListener(Event.RESIZE, onResize);
  197. _hideMouseTimer.addEventListener(TimerEvent.TIMER, hideMouseTimer);
  198. _checkAudioTimer.addEventListener(TimerEvent.TIMER, checkAudioTimer);
  199. _connection.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus);
  200. _connection.addEventListener(AsyncErrorEvent.ASYNC_ERROR, onAsyncError);
  201. _scaleWidth = Std.int(_stage.stageWidth);
  202. _scaleHeight = Std.int(_stage.stageHeight);
  203. //}
  204. }
  205. //}
  206. public function init():Void {
  207. var parameters:Dynamic<String> = flash.Lib.current.loaderInfo.parameters;
  208. if (parameters.poster == "" && _streamType == StreamType.YOUTUBE && _mediaSource != null) {
  209. _ytCue = true;
  210. noAPITrigger = true;
  211. load(_mediaSource, _type, _streamType, _server);
  212. noAPITrigger = false;
  213. } else if(_streamType == StreamType.USER){
  214. getUserMedia();
  215. }
  216. }
  217. private function getUserMedia():Void {
  218. var status;
  219. var aspect;
  220. _cam = Camera.getCamera();
  221. _mediaSource = '';
  222. if(camLength > 0){
  223. _cam.addEventListener(StatusEvent.STATUS, userStatusHandler);
  224. _video.visible = false;
  225. aspect = _cam.height / _cam.width;
  226. _cam.setMode(640, Std.int(640 * aspect), 25, true);
  227. _video.attachCamera(_cam);
  228. if(!_cam.muted){
  229. status = new StatusEvent('status', false, false, 'Camera.Unmuted');
  230. userStatusHandler(status);
  231. }
  232. } else {
  233. callEvents(PlayerEvents.USERNOTSUPPORTED);
  234. }
  235. }
  236. public function attachUsermedia():Void {
  237. if(_streamType == StreamType.USER){
  238. addEventListener(PlayerEvents.PLAY_PAUSE, onUserPlayPause);
  239. if(_isPlaying){
  240. onUserPlayPause();
  241. }
  242. }
  243. }
  244. public function detachUsermedia():Void {
  245. if(_streamType == StreamType.USER){
  246. removeEventListener(PlayerEvents.PLAY_PAUSE, onUserPlayPause);
  247. _video.attachCamera(null);
  248. }
  249. }
  250. private function onUserPlayPause(event = null){
  251. var data;
  252. if(_isPlaying){
  253. data = {
  254. width: _cam.width,
  255. height: _cam.height,
  256. duration: Math.POSITIVE_INFINITY
  257. };
  258. _video.attachCamera(_cam);
  259. _video.visible = true;
  260. if(_firstLoad){
  261. onMetaData(data);
  262. }
  263. } else {
  264. _video.attachCamera(null);
  265. }
  266. }
  267. private function userStatusHandler(event){
  268. if(event.code == 'Camera.Unmuted'){
  269. _videoHeight = event.target.height;
  270. _videoWidth = event.target.width;
  271. _originalAspectRatio = AspectRatio.getAspectRatio(_videoWidth, _videoHeight);
  272. _mediaLoaded = true;
  273. if (_aspectRatio <= 0) {
  274. _aspectRatio = _originalAspectRatio;
  275. }
  276. _video.attachCamera(null);
  277. callEvents(PlayerEvents.USERSUCCESS);
  278. } else {
  279. callEvents(PlayerEvents.USERDENIED);
  280. }
  281. }
  282. public function createScreenShot() {
  283. var ret = '';
  284. if(_mediaLoaded && !_firstLoad){
  285. var vwidth = Std.int(_videoWidth);
  286. var vheight = Std.int(_videoHeight);
  287. var matrix:Matrix = new Matrix();
  288. //return 'sw: '+ swidth+' sh: '+ sheight+' vw: '+ vwidth +' vh: '+ vheight;
  289. matrix.scale(vwidth / _scaleWidth, vheight / _scaleHeight);
  290. var qImageData:BitmapData = new BitmapData(vwidth, vheight, false, 0x00FF00);
  291. var byteArray:ByteArray = new ByteArray();
  292. qImageData.draw(_video, matrix, null, null, null, true);
  293. qImageData.encode(new Rectangle(0, 0, vwidth, vheight), new flash.display.JPEGEncoderOptions(), byteArray);
  294. ret = Utils.enocdeBytesData(byteArray);
  295. }
  296. return ret;
  297. }
  298. //{Timers
  299. /**
  300. * Timer that hides the mouse pointer when it is idle and dispatch the PlayerEvents.MOUSE_HIDE
  301. * @param event
  302. */
  303. private function hideMouseTimer(event:TimerEvent):Void {
  304. if (_fullscreen) {
  305. if (_mouseVisible) {
  306. _mouseVisible = false;
  307. }
  308. else {
  309. Mouse.hide();
  310. callEvents(PlayerEvents.MOUSE_HIDE);
  311. _hideMouseTimer.stop();
  312. }
  313. }
  314. }
  315. /**
  316. * To check if the sound finished playing
  317. * @param event
  318. */
  319. private function checkAudioTimer(event:TimerEvent):Void {
  320. if (_soundChannel.position + 100 >= _sound.length) {
  321. _isPlaying = false;
  322. _mediaEndReached = true;
  323. callEvents(PlayerEvents.PLAYBACK_FINISHED);
  324. _checkAudioTimer.stop();
  325. }
  326. }
  327. //}
  328. //{Events
  329. /**
  330. * Callback after bandwidth calculation for rtmp streams
  331. */
  332. private function onBWDone():Void {
  333. //Need to study this more
  334. }
  335. /**
  336. * Triggers error event on rtmp connections
  337. * @param event
  338. */
  339. private function onAsyncError(event:AsyncErrorEvent):Void {
  340. //TODO: Should trigger event for controls to display error message
  341. trace(event.error);
  342. }
  343. /**
  344. * Checks if connection failed or succeed
  345. * @param event
  346. */
  347. private function onNetStatus(event:NetStatusEvent):Void {
  348. switch (event.info.code)
  349. {
  350. case "NetConnection.Connect.Success":
  351. if (_streamType == StreamType.RTMP) {
  352. _stream = new NetStream(_connection);
  353. _stream.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus);
  354. _stream.bufferTime = 10;
  355. _stream.play(Utils.rtmpSourceParser(_mediaSource), true);
  356. _stream.client = this;
  357. if (_type == InputType.VIDEO) {_video.attachNetStream(_stream); }
  358. }
  359. callEvents(PlayerEvents.CONNECTION_SUCCESS);
  360. case "NetStream.Play.StreamNotFound":
  361. trace("Stream not found: " + _mediaSource); //Replace with a dispatch for error event
  362. callEvents(PlayerEvents.CONNECTION_FAILED);
  363. case "NetStream.Play.Stop":
  364. if (_streamType != StreamType.RTMP) {
  365. if (_isPlaying) { _stream.togglePause(); }
  366. _isPlaying = false;
  367. _mediaEndReached = true;
  368. callEvents(PlayerEvents.PLAYBACK_FINISHED);
  369. }
  370. case "NetStream.Play.Start":
  371. _mediaEndReached = false;
  372. if (_isPlaying && (_stream.bytesLoaded != _stream.bytesTotal || _streamType == StreamType.RTMP)) {
  373. callEvents(PlayerEvents.BUFFERING);
  374. }
  375. case "NetStream.Seek.Notify":
  376. _mediaEndReached = false;
  377. if (_streamType == StreamType.RTMP) {
  378. _isPlaying = true;
  379. callEvents(PlayerEvents.PLAY_PAUSE);
  380. callEvents(PlayerEvents.BUFFERING);
  381. }
  382. case "NetStream.Buffer.Empty":
  383. if (_stream.bytesLoaded != _stream.bytesTotal) {
  384. callEvents(PlayerEvents.BUFFERING);
  385. }
  386. case "NetStream.Buffer.Full":
  387. callEvents(PlayerEvents.NOT_BUFFERING);
  388. case "NetStream.Buffer.Flush":
  389. if (_stream.bytesLoaded == _stream.bytesTotal) {
  390. _downloadCompleted = true;
  391. }
  392. }
  393. }
  394. /**
  395. * Proccess keyboard shortcuts
  396. * @param event
  397. */
  398. private function onKeyDown(event:KeyboardEvent):Void {
  399. var F_KEY:UInt = 70;
  400. var M_KEY:UInt = 77;
  401. switch(event.keyCode)
  402. {
  403. case F_KEY:
  404. toggleFullscreen();
  405. case M_KEY:
  406. toggleMute();
  407. case Keyboard.SPACE:
  408. togglePlay();
  409. }
  410. }
  411. /**
  412. * IF player is full screen shows the mouse when gets hide
  413. * @param event
  414. */
  415. private function onMouseMove(event:MouseEvent):Void {
  416. if (_fullscreen && !_mouseVisible) {
  417. if (!_hideMouseTimer.running) {
  418. _hideMouseTimer.start();
  419. }
  420. _mouseVisible = true;
  421. Mouse.show();
  422. callEvents(PlayerEvents.MOUSE_SHOW);
  423. }
  424. }
  425. /**
  426. * Resize video player
  427. * @param event
  428. */
  429. private function onResize(event:Event):Void {
  430. resizeAndCenterPlayer();
  431. }
  432. /**
  433. * Dispath a full screen event to listeners as redraw player an takes care of some other aspects
  434. * @param event
  435. */
  436. private function onFullScreen(event:FullScreenEvent):Void {
  437. _fullscreen = event.fullScreen;
  438. if (!event.fullScreen) {
  439. Mouse.show();
  440. callEvents(PlayerEvents.MOUSE_SHOW);
  441. _mouseVisible = true;
  442. }
  443. else {
  444. _mouseVisible = true;
  445. _hideMouseTimer.start();
  446. }
  447. resizeAndCenterPlayer();
  448. callEvents(PlayerEvents.FULLSCREEN);
  449. }
  450. /**
  451. * Sits for any cue points available
  452. * @param data
  453. * @note Planned future implementation
  454. */
  455. private function onCuePoint(data:Dynamic):Void {
  456. }
  457. /**
  458. * After a video is loaded this callback gets the video information at start and stores it on variables
  459. * @param data
  460. */
  461. private function onMetaData(data:Dynamic):Void {
  462. var i, fields;
  463. if (_firstLoad) {
  464. _isPlaying = _preLoading ? false : true;
  465. _firstLoad = false;
  466. if (data.width) {
  467. _videoWidth = data.width;
  468. _videoHeight = data.height;
  469. }
  470. else {
  471. _videoWidth = _video.width;
  472. _videoHeight = _video.height;
  473. }
  474. _naturalWidth = _video.videoWidth;
  475. _naturalHeight = _video.videoHeight;
  476. if (_naturalWidth == 0) {
  477. _naturalWidth = _videoWidth;
  478. }
  479. if (_naturalHeight == 0) {
  480. _naturalHeight = _videoHeight;
  481. }
  482. //Store seekpoints times
  483. if (data.hasOwnProperty("seekpoints")) {
  484. for (position in Reflect.fields(data.seekpoints)) {
  485. _seekPoints.push(Reflect.field(data.seekpoints, position).time);
  486. }
  487. }
  488. else if (data.hasOwnProperty("keyframes")) {
  489. for (position in Reflect.fields(data.keyframes.times)) {
  490. _seekPoints.push(Reflect.field(data.keyframes.times, position));
  491. }
  492. }
  493. _mediaLoaded = true;
  494. _mediaDuration = data.duration;
  495. _originalAspectRatio = AspectRatio.getAspectRatio(_videoWidth, _videoHeight);
  496. if (_aspectRatio <= 0) {
  497. _aspectRatio = _originalAspectRatio;
  498. }
  499. fields = Reflect.fields(data);
  500. fullMetaData = { };
  501. for (i in fields) {
  502. Reflect.setField(fullMetaData, i, Reflect.field(data, i));
  503. }
  504. callEvents(PlayerEvents.MEDIA_INITIALIZED);
  505. resizeAndCenterPlayer();
  506. //Retrieve the volume that user selected last time
  507. setVolume(_userSettings.getVolume());
  508. }
  509. }
  510. /**
  511. * Dummy function invoked for pseudostream servers
  512. * @param data
  513. */
  514. private function onLastSecond(data:Dynamic):Void {
  515. trace("last second pseudostream");
  516. }
  517. /**
  518. * Broadcast Timeupdate and Duration
  519. */
  520. private function onEnterFrame(event:Event):Void {
  521. if (getDuration() > 0 && _lastTime != getCurrentTime()) {
  522. _lastTime = getCurrentTime();
  523. callEvents(PlayerEvents.TIME);
  524. }
  525. if (getBytesLoaded() > 0 && _lastProgress < getBytesLoaded()) {
  526. _lastProgress = getBytesLoaded();
  527. callEvents(PlayerEvents.PROGRESS);
  528. }
  529. }
  530. /**
  531. * Triggers when playbacks end on rtmp streaming server
  532. */
  533. private function onPlayStatus(info:Dynamic):Void {
  534. _isPlaying = false;
  535. _mediaEndReached = true;
  536. callEvents(PlayerEvents.PLAYBACK_FINISHED);
  537. }
  538. /**
  539. * When sound finished downloading
  540. * @param event
  541. */
  542. private function onSoundComplete(event:Event) {
  543. _mediaDuration = _sound.length / 1000;
  544. _downloadCompleted = true;
  545. callEvents(PlayerEvents.MEDIA_INITIALIZED);
  546. }
  547. /**
  548. * Mimic stream onMetaData
  549. * @param event
  550. */
  551. private function onSoundID3(event:Event) {
  552. if (_firstLoad) {
  553. _soundChannel = _sound.play();
  554. _checkAudioTimer.start();
  555. _isPlaying = true;
  556. _firstLoad = false;
  557. _mediaLoaded = true;
  558. _mediaDuration = ((_sound.bytesTotal / _sound.bytesLoaded) * _sound.length) / 1000;
  559. _aspectRatio = AspectRatio.getAspectRatio(_videoWidth, _videoHeight);
  560. _originalAspectRatio = _aspectRatio;
  561. _id3Info = _sound.id3;
  562. callEvents(PlayerEvents.CONNECTION_SUCCESS);
  563. callEvents(PlayerEvents.MEDIA_INITIALIZED);
  564. resizeAndCenterPlayer();
  565. //Retrieve the volume that user selected last time
  566. setVolume(_userSettings.getVolume());
  567. }
  568. }
  569. /**
  570. * Dispatch connection failed event on error
  571. * @param event
  572. */
  573. private function onSoundIOError(event:IOErrorEvent) {
  574. callEvents(PlayerEvents.CONNECTION_FAILED);
  575. }
  576. /**
  577. * Monitor sound download progress
  578. * @param event
  579. */
  580. private function onSoundProgress(event:ProgressEvent) {
  581. var oldDuration = _mediaDuration;
  582. if (_sound.isBuffering) {
  583. callEvents(PlayerEvents.BUFFERING);
  584. }
  585. else {
  586. callEvents(PlayerEvents.NOT_BUFFERING);
  587. }
  588. _mediaDuration = ((_sound.bytesTotal / _sound.bytesLoaded) * _sound.length) / 1000;
  589. if (_mediaDuration != oldDuration) {
  590. callEvents(PlayerEvents.MEDIA_INITIALIZED);
  591. }
  592. }
  593. /**
  594. * Initializes the youtube loader object
  595. * @param event
  596. */
  597. private function onYouTubeLoaderInit(event:Event):Void {
  598. _youtubeLoader.content.addEventListener("onReady", onYoutubeReady);
  599. _youtubeLoader.content.addEventListener("onError", onYoutubeError);
  600. _youtubeLoader.content.addEventListener("onStateChange", onYoutubeStateChange);
  601. _youtubeLoader.content.addEventListener("onPlaybackQualityChange", onYoutubePlaybackQualityChange);
  602. }
  603. /**
  604. * This event is fired when the player is loaded and initialized, meaning it is ready to receive API calls.
  605. */
  606. private function onYoutubeReady(event:Event):Void {
  607. _movieClip.addChild(_youtubeLoader.content);
  608. _movieClip.setChildIndex(_youtubeLoader.content, 0);
  609. _ytReady = true;
  610. Reflect.field(_youtubeLoader.content, "setSize")(_stage.stageWidth, _stage.stageHeight);
  611. if (_ytCue && !_isPlaying && !_requestedPlay) {
  612. Reflect.field(_youtubeLoader.content, "cueVideoByUrl")(Utils.youtubeSourceParse(_mediaSource), 0, Utils.youtubeQualitySourceParse(_mediaSource));
  613. } else {
  614. Reflect.field(_youtubeLoader.content, "loadVideoByUrl")(Utils.youtubeSourceParse(_mediaSource), 0, Utils.youtubeQualitySourceParse(_mediaSource));
  615. callEvents(PlayerEvents.BUFFERING);
  616. }
  617. }
  618. /**
  619. * This event is fired whenever the player's state changes. Possible values are unstarted (-1), ended (0),
  620. * playing (1), paused (2), buffering (3), video cued (5). When the SWF is first loaded it will broadcast
  621. * an unstarted (-1) event. When the video is cued and ready to play it will broadcast a video cued event (5).
  622. * @param event
  623. */
  624. private function onYoutubeStateChange(event:Event):Void {
  625. var status:UInt = Std.parseInt(Reflect.field(event, "data"));
  626. var oldPlaying:Bool = _isPlaying;
  627. var quality;
  628. if (!_mediaLoaded && _ytCue && !_isPlaying && _requestedPlay) {
  629. play();
  630. }
  631. _mediaLoaded = true;
  632. switch(status)
  633. {
  634. case -1:
  635. callEvents(PlayerEvents.BUFFERING);
  636. case 0:
  637. _isPlaying = false;
  638. _mediaEndReached = true;
  639. callEvents(PlayerEvents.PLAYBACK_FINISHED);
  640. case 1:
  641. _isPlaying = true;
  642. if (_firstLoad) {
  643. _videoWidth = _stage.stageWidth;
  644. _videoHeight = _stage.stageHeight;
  645. quality = Reflect.field(_youtubeLoader.content, "getPlaybackQuality")();
  646. switch(quality)
  647. {
  648. case 'small':
  649. _naturalHeight = 240;
  650. _naturalWidth = 320;
  651. case 'medium':
  652. _naturalHeight = 360;
  653. _naturalWidth = 640;
  654. case 'large':
  655. _naturalHeight = 480;
  656. _naturalWidth = 853;
  657. case 'hd720':
  658. _naturalHeight = 720;
  659. _naturalWidth = 1280;
  660. case 'hd1080':
  661. _naturalHeight = 1080;
  662. _naturalWidth = 1920;
  663. case 'highres':
  664. _naturalHeight = 1080;
  665. _naturalWidth = 1920;
  666. }
  667. if (_naturalWidth == 0) {
  668. _naturalWidth = _videoWidth;
  669. }
  670. if (_naturalHeight == 0) {
  671. _naturalHeight = _videoHeight;
  672. }
  673. _firstLoad = false;
  674. _mediaDuration = Reflect.field(_youtubeLoader.content, "getDuration")();
  675. _aspectRatio = AspectRatio.getAspectRatio(_videoWidth, _videoHeight);
  676. _originalAspectRatio = _aspectRatio;
  677. callEvents(PlayerEvents.CONNECTION_SUCCESS);
  678. callEvents(PlayerEvents.MEDIA_INITIALIZED);
  679. resizeAndCenterPlayer();
  680. //Retrieve the volume that user selected last time
  681. setVolume(_userSettings.getVolume());
  682. }
  683. callEvents(PlayerEvents.NOT_BUFFERING);
  684. if (oldPlaying != _isPlaying) {
  685. callEvents(PlayerEvents.PLAY_PAUSE);
  686. }
  687. case 2:
  688. _isPlaying = false;
  689. callEvents(PlayerEvents.NOT_BUFFERING);
  690. if (oldPlaying != _isPlaying) {
  691. callEvents(PlayerEvents.PLAY_PAUSE);
  692. }
  693. case 3:
  694. callEvents(PlayerEvents.BUFFERING);
  695. case 5:
  696. callEvents(PlayerEvents.NOT_BUFFERING);
  697. }
  698. }
  699. /**
  700. * This event is fired whenever the video playback quality changes. For example, if you call the
  701. * setPlaybackQuality(suggestedQuality) function, this event will fire if the playback quality actually
  702. * changes. Your code should respond to the event and should not assume that the quality will automatically
  703. * change when the setPlaybackQuality(suggestedQuality) function is called. Similarly, your code should not
  704. * assume that playback quality will only change as a result of an explicit call to setPlaybackQuality or any
  705. * other function that allows you to set a suggested playback quality.
  706. *
  707. * The value that the event broadcasts is the new playback quality. Possible values are "small", "medium",
  708. * "large" and "hd720".
  709. * @param event
  710. */
  711. private function onYoutubePlaybackQualityChange(event:Event):Void {
  712. //trace(Reflect.field(event, "data"));
  713. }
  714. /**
  715. * This event is fired when an error in the player occurs. The possible error codes are 100, 101,
  716. * and 150. The 100 error code is broadcast when the video requested is not found. This occurs when
  717. * a video has been removed (for any reason), or it has been marked as private. The 101 error code is
  718. * broadcast when the video requested does not allow playback in the embedded players. The error code
  719. * 150 is the same as 101, it's just 101 in disguise!
  720. * @param event
  721. */
  722. private function onYoutubeError(event:Event):Void {
  723. trace(Reflect.field(event, "data"));
  724. }
  725. //}
  726. //{Private Methods
  727. /**
  728. * Function used each time is needed to dispatch an event
  729. * @param type
  730. */
  731. private function callEvents(type:String):Void {
  732. var playerEvent:PlayerEvents = new PlayerEvents(type, true);
  733. playerEvent.aspectRatio = getAspectRatio();
  734. playerEvent.duration = getDuration();
  735. playerEvent.fullscreen = isFullscreen();
  736. playerEvent.mute = getMute();
  737. playerEvent.volume = getVolume();
  738. playerEvent.width = _video.width;
  739. playerEvent.height = _video.height;
  740. playerEvent.stream = getNetStream();
  741. playerEvent.sound = getSound();
  742. playerEvent.time = getCurrentTime();
  743. playerEvent.id3Info = getId3Info();
  744. playerEvent.seekTime = lastSeekTime;
  745. dispatchEvent(playerEvent);
  746. }
  747. /**
  748. * Reposition and resizes the video player to fit on screen
  749. */
  750. private function resizeAndCenterPlayer():Void {
  751. if (_streamType != StreamType.YOUTUBE) {
  752. _video.height = _stage.stageHeight;
  753. _video.width = _video.height * _aspectRatio;
  754. _video.x = (_stage.stageWidth / 2) - (_video.width / 2);
  755. _video.y = 0;
  756. if (_video.width > _stage.stageWidth && _aspectRatio == _originalAspectRatio) {
  757. var aspectRatio:Float = _videoHeight / _videoWidth;
  758. _video.width = _stage.stageWidth;
  759. _video.height = aspectRatio * _video.width;
  760. _video.x = 0;
  761. _video.y = (_stage.stageHeight / 2) - (_video.height / 2);
  762. }
  763. _videoMask.graphics.clear();
  764. _videoMask.graphics.lineStyle();
  765. _videoMask.graphics.beginFill(0x000000, 0);
  766. _videoMask.graphics.drawRect(_video.x, _video.y, _video.width, _video.height);
  767. _videoMask.graphics.endFill();
  768. }
  769. else {
  770. Reflect.field(_youtubeLoader.content, "setSize")(_stage.stageWidth, _stage.stageHeight);
  771. _videoMask.graphics.clear();
  772. _videoMask.graphics.lineStyle();
  773. _videoMask.graphics.beginFill(0x000000, 0);
  774. _videoMask.graphics.drawRect(0, 0, _stage.stageWidth, _stage.stageHeight);
  775. _videoMask.graphics.endFill();
  776. }
  777. callEvents(PlayerEvents.RESIZE);
  778. }
  779. /**
  780. * Check the best seek point available if the seekpoints array is available
  781. * @param time time in seconds
  782. * @return best seek point in seconds or given one if no seekpoints array is available
  783. */
  784. private function getBestSeekPoint(time:Float):Float {
  785. if (_seekPoints.length > 0) {
  786. var timeOne:String = "0";
  787. var timeTwo:String = "0";
  788. for (prop in Reflect.fields(_seekPoints)) {
  789. if (Reflect.field(_seekPoints, prop) < time) {
  790. timeOne = prop;
  791. }
  792. else {
  793. timeTwo = prop;
  794. break;
  795. }
  796. }
  797. if (time - _seekPoints[Std.parseInt(timeOne)] < _seekPoints[Std.parseInt(timeTwo)] - time) {
  798. return _seekPoints[Std.parseInt(timeOne)];
  799. }
  800. else {
  801. return _seekPoints[Std.parseInt(timeTwo)];
  802. }
  803. }
  804. return time;
  805. }
  806. /**
  807. * Checks if the given seek time is already buffered
  808. * @param time time in seconds
  809. * @return true if can seek false if not in buffer
  810. */
  811. private function canSeek(time:Float):Bool {
  812. if (_type == InputType.VIDEO) {
  813. time = getBestSeekPoint(time);
  814. }
  815. var cacheTotal = Math.floor((getDuration() - _startTime) * (getBytesLoaded() / getBytesTotal())) - 1;
  816. if (time >= _startTime && time < _startTime + cacheTotal) {
  817. return true;
  818. }
  819. return false;
  820. }
  821. //}
  822. //{Public methods
  823. /**
  824. * Preload a video without playing
  825. */
  826. public function preload():Void {
  827. if (!_requestedLoad && !_mediaLoaded && _mediaSource != "" && !_requestedPlay) {
  828. var isVideo = (_type == InputType.VIDEO && (_streamType == StreamType.FILE || _streamType == StreamType.PSEUDOSTREAM));
  829. var isAudio = (_type == InputType.AUDIO && _streamType == StreamType.FILE);
  830. if (isVideo || isAudio) {
  831. stopAndClose();
  832. load(_mediaSource, _type, _streamType, _server, true);
  833. _stopped = false;
  834. _mediaLoaded = false;
  835. _firstLoad = true;
  836. _startTime = 0;
  837. _downloadCompleted = false;
  838. _preLoading = true;
  839. _allowPreloadedPlay = true;
  840. }
  841. }
  842. }
  843. //{Public methods
  844. /**
  845. * Loads a video and starts playing it
  846. * @param video video url to load
  847. */
  848. public function load(source:String, type:String = "video", streamType:String = "file", server:String = "", preload:Bool = false):Void {
  849. if (!_requestedLoad && !_mediaLoaded && (_streamType != StreamType.YOUTUBE || !_loadedYoutube)) {
  850. stopAndClose();
  851. _type = type;
  852. _streamType = streamType;
  853. _mediaSource = source;
  854. _stopped = false;
  855. _mediaLoaded = false;
  856. _firstLoad = true;
  857. _startTime = 0;
  858. _downloadCompleted = false;
  859. _seekPoints = new Array();
  860. _server = server;
  861. _requestedLoad = true;
  862. if (!preload) {
  863. callEvents(PlayerEvents.BUFFERING);
  864. }
  865. if (_streamType == StreamType.YOUTUBE) {
  866. Security.allowDomain("*");
  867. Security.allowDomain("www.youtube.com");
  868. Security.allowDomain("youtube.com");
  869. Security.allowDomain("i4.ytimg.com");
  870. Security.allowDomain("s.ytimg.com");
  871. Security.allowDomain("i.ytimg.com");
  872. _youtubeLoader = new Loader();
  873. _youtubeLoader.contentLoaderInfo.addEventListener(Event.INIT, onYouTubeLoaderInit);
  874. _youtubeLoader.load(new URLRequest("http://www.youtube.com/apiplayer?version=3"));
  875. _loadedYoutube = true;
  876. }
  877. else if (_type == InputType.VIDEO && (_streamType == StreamType.FILE || _streamType == StreamType.PSEUDOSTREAM)) {
  878. Security.allowDomain("*");
  879. _connection.connect(null);
  880. _stream = new NetStream(_connection);
  881. _stream.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus);
  882. _stream.bufferTime = _bufferTime;
  883. _stream.checkPolicyFile = true;
  884. _stream.play(source);
  885. _stream.client = this;
  886. _video.attachNetStream(_stream);
  887. if (preload) {
  888. pause();
  889. _isPlaying = false;
  890. }
  891. if (!preload || !_hasPoster) {
  892. _video.attachNetStream(_stream);
  893. }
  894. }
  895. else if (_streamType == StreamType.RTMP) {
  896. _connection.connect(_server);
  897. }
  898. else if (_type == InputType.AUDIO && _streamType == StreamType.FILE) {
  899. _sound.load(new URLRequest(source));
  900. try {
  901. _soundChannel = _sound.play();
  902. if (preload) {
  903. _soundChannel.stop();
  904. _isPlaying = false;
  905. } else {
  906. _isPlaying = true;
  907. }
  908. _firstLoad = false;
  909. _mediaLoaded = true;
  910. } catch (error:IOError) { }
  911. }
  912. }
  913. }
  914. /**
  915. * Closes the connection and makes player available for another video
  916. */
  917. public function stopAndClose():Void {
  918. if (_mediaLoaded || _requestedLoad) {
  919. _requestedLoad = false;
  920. _mediaLoaded = false;
  921. _isPlaying = false;
  922. _stopped = true;
  923. _startTime = 0;
  924. _allowPreloadedPlay = false;
  925. if (_streamType == StreamType.YOUTUBE) {
  926. Reflect.field(_youtubeLoader.content, "destroy")();
  927. }
  928. else if (_type == InputType.VIDEO) {
  929. _stream.close();
  930. }
  931. else {
  932. _soundChannel.stop();
  933. _sound.close();
  934. }
  935. }
  936. callEvents(PlayerEvents.STOP_CLOSE);
  937. }
  938. /**
  939. * Seeks video player to a given time in seconds
  940. * @param seekTime time in seconds to seek
  941. * @return current play time after seeking
  942. */
  943. public function seek(seekTime:Float):Float {
  944. if (_startTime <= 1 && _downloadCompleted) {
  945. if (_type == InputType.VIDEO || _streamType == StreamType.RTMP) {
  946. _stream.seek(seekTime);
  947. }
  948. else if (_type == InputType.AUDIO) {
  949. _soundChannel.stop();
  950. _soundChannel = _sound.play(seekTime * 1000);
  951. if (!_isPlaying) {
  952. _soundChannel.stop();
  953. }
  954. setVolume(_userSettings.getVolume());
  955. }
  956. }
  957. else if (_seekPoints.length > 0 && _streamType == StreamType.PSEUDOSTREAM) {
  958. seekTime = getBestSeekPoint(seekTime);
  959. if (canSeek(seekTime)) {
  960. _stream.seek(seekTime - _startTime);
  961. }
  962. else if (seekTime != _startTime) {
  963. _startTime = seekTime;
  964. var url:String;
  965. if (_mediaSource.indexOf("?") != -1) {
  966. url = _mediaSource + "&start=" + seekTime;
  967. }
  968. else {
  969. url = _mediaSource + "?start=" + seekTime;
  970. }
  971. _stream.play(url);
  972. }
  973. }
  974. else if (_streamType == StreamType.YOUTUBE) {
  975. if (!canSeek(seekTime)) {
  976. if (_ytReady) {
  977. _startTime = seekTime;
  978. Reflect.field(_youtubeLoader.content, "seekTo")(seekTime);
  979. }
  980. }
  981. else if (_ytReady) {
  982. Reflect.field(_youtubeLoader.content, "seekTo")(seekTime);
  983. }
  984. }
  985. else if (_streamType == StreamType.RTMP) {
  986. // seekTime = getBestSeekPoint(seekTime); //Not Needed?
  987. _stream.seek(seekTime);
  988. }
  989. else if (canSeek(seekTime)) {
  990. if (_type == InputType.VIDEO || _streamType == StreamType.RTMP) {
  991. _stream.seek(seekTime);
  992. }
  993. else if (_type == InputType.AUDIO) {
  994. _soundChannel.stop();
  995. _soundChannel = _sound.play(seekTime * 1000);
  996. if (!_isPlaying) {
  997. _soundChannel.stop();
  998. }
  999. setVolume(_userSettings.getVolume());
  1000. }
  1001. }
  1002. lastSeekTime = seekTime;
  1003. callEvents(PlayerEvents.SEEK);
  1004. return seekTime;
  1005. }
  1006. /**
  1007. * To check wheter the media is playing
  1008. * @return true if is playing false otherwise
  1009. */
  1010. public function isPlaying():Bool {
  1011. return _isPlaying;
  1012. }
  1013. /**
  1014. * Swithces between play and pause
  1015. */
  1016. public function togglePlay():Bool {
  1017. if (_isPlaying) {
  1018. this.pause();
  1019. } else {
  1020. this.play();
  1021. }
  1022. return _isPlaying;
  1023. }
  1024. /**
  1025. * pause
  1026. */
  1027. public function pause():Bool {
  1028. _requestedPlay = false;
  1029. if (!_mediaEndReached) {
  1030. if (_streamType == StreamType.YOUTUBE) {
  1031. if (_ytReady) {
  1032. Reflect.field(_youtubeLoader.content, "pauseVideo")();
  1033. }
  1034. }
  1035. else if (_type == InputType.VIDEO || _streamType == StreamType.RTMP) {
  1036. _stream.pause();
  1037. }
  1038. else if (_type == InputType.AUDIO) {
  1039. _soundChannel.stop();
  1040. }
  1041. }
  1042. if (_isPlaying) {
  1043. _isPlaying = false;
  1044. callEvents(PlayerEvents.PLAY_PAUSE);
  1045. if (!_mediaLoaded) {
  1046. callEvents(PlayerEvents.NOT_BUFFERING);
  1047. }
  1048. }
  1049. return _isPlaying;
  1050. }
  1051. /**
  1052. *
  1053. */
  1054. public function play():Bool {
  1055. if(_streamType != StreamType.USER){
  1056. _video.attachNetStream(_stream);
  1057. }
  1058. _preLoading = false;
  1059. _requestedPlay = true;
  1060. if (_mediaLoaded || _allowPreloadedPlay) {
  1061. if (_mediaEndReached) {
  1062. _mediaEndReached = false;
  1063. if (_streamType == StreamType.YOUTUBE) {
  1064. Reflect.field(_youtubeLoader.content, "seekTo")(0);
  1065. Reflect.field(_youtubeLoader.content, "playVideo")();
  1066. }
  1067. else if (_type == InputType.VIDEO || _streamType == StreamType.RTMP) {
  1068. _stream.seek(0);
  1069. _stream.resume();
  1070. }
  1071. else if (_type == InputType.AUDIO) {
  1072. _checkAudioTimer.start();
  1073. _soundChannel = _sound.play();
  1074. setVolume(_userSettings.getVolume());
  1075. }
  1076. }
  1077. else {
  1078. if (_streamType == StreamType.YOUTUBE) {
  1079. if (_ytReady) {
  1080. Reflect.field(_youtubeLoader.content, "playVideo")();
  1081. }
  1082. }
  1083. else if (_type == InputType.VIDEO || _streamType == StreamType.RTMP) {
  1084. _stream.resume();
  1085. }
  1086. else if (_type == InputType.AUDIO) {
  1087. if (!_isPlaying) {
  1088. //If end of audio reached start from beggining
  1089. if (_soundChannel.position + 100 >= _sound.length) {
  1090. _soundChannel = _sound.play();
  1091. }
  1092. else {
  1093. _soundChannel = _sound.play(_soundChannel.position);
  1094. }
  1095. }
  1096. setVolume(_userSettings.getVolume());
  1097. }
  1098. }
  1099. if (!_isPlaying) {
  1100. _isPlaying = true;
  1101. callEvents(PlayerEvents.PLAY_PAUSE);
  1102. }
  1103. return _isPlaying;
  1104. }
  1105. else if (_mediaSource != "") {
  1106. load(_mediaSource, _type, _streamType, _server);
  1107. callEvents(PlayerEvents.BUFFERING);
  1108. _isPlaying = true;
  1109. return true;
  1110. }
  1111. return true;
  1112. }
  1113. /**
  1114. * Switches on or off fullscreen
  1115. * @return true if fullscreen otherwise false
  1116. */
  1117. public function toggleFullscreen():Bool {
  1118. if (_fullscreen) {
  1119. _stage.displayState = StageDisplayState.NORMAL;
  1120. _stage.focus = _stage;
  1121. return false;
  1122. }
  1123. else {
  1124. if (_useHardWareScaling) {
  1125. //Match full screen aspec ratio to desktop
  1126. var aspectRatio = Capabilities.screenResolutionY / Capabilities.screenResolutionX;
  1127. _stage.fullScreenSourceRect = new Rectangle(0, 0, _videoWidth, _videoWidth * aspectRatio);
  1128. }
  1129. else {
  1130. //Use desktop resolution
  1131. _stage.fullScreenSourceRect = new Rectangle(0, 0, Capabilities.screenResolutionX, Capabilities.screenResolutionY);
  1132. }
  1133. _stage.displayState = StageDisplayState.FULL_SCREEN;
  1134. _stage.focus = _stage;
  1135. return true;
  1136. }
  1137. }
  1138. /**
  1139. * Toggles betewen high and low quality image rendering
  1140. * @return true if quality high false otherwise
  1141. */
  1142. public function toggleQuality():Bool {
  1143. if (_videoQualityHigh) {
  1144. _video.smoothing = false;
  1145. _video.deblocking = 1;
  1146. }
  1147. else {
  1148. _video.smoothing = true;
  1149. _video.deblocking = 5;
  1150. }
  1151. _videoQualityHigh = _videoQualityHigh ? false : true;
  1152. return _videoQualityHigh;
  1153. }
  1154. /**
  1155. * Mutes or unmutes the sound
  1156. * @return true if muted false if unmuted
  1157. */
  1158. public function toggleMute() {
  1159. this.mute(!_soundMuted);
  1160. }
  1161. public function mute(goMuted:Bool) {
  1162. var soundTransform:SoundTransform = new SoundTransform();
  1163. //unmute sound
  1164. if (!goMuted) {
  1165. _soundMuted = false;
  1166. soundTransform.volume = _volume;
  1167. }
  1168. //mute sound
  1169. else {
  1170. _soundMuted = true;
  1171. _volume = _stream.soundTransform.volume;
  1172. soundTransform.volume = 0;
  1173. _stream.soundTransform = soundTransform;
  1174. _userSettings.setVolume(0);
  1175. }
  1176. if (_streamType == StreamType.YOUTUBE) {
  1177. if (this._ytReady) {
  1178. Reflect.field(_youtubeLoader.content, "setVolume")(soundTransform.volume * 100);
  1179. }
  1180. }
  1181. else if (_type == InputType.VIDEO || _streamType == StreamType.RTMP) {
  1182. _stream.soundTransform = soundTransform;
  1183. }
  1184. else if (_type == InputType.AUDIO) {
  1185. _soundChannel.soundTransform = soundTransform;
  1186. setVolume(_userSettings.getVolume());
  1187. }
  1188. callEvents(PlayerEvents.MUTE);
  1189. }
  1190. /**
  1191. * Check if player is running on fullscreen mode
  1192. * @return true if fullscreen false if not
  1193. */
  1194. public function isFullscreen():Bool {
  1195. return _stage.displayState == StageDisplayState.FULL_SCREEN;
  1196. }
  1197. //{Setters
  1198. /**
  1199. * Set input type
  1200. * @param type Allowable values are audio, video
  1201. */
  1202. public function setType(type:String):Void {
  1203. _type = type;
  1204. }
  1205. /**
  1206. * Set streaming type
  1207. * @param streamType Allowable values are file, http, rmtp
  1208. */
  1209. public function setStreamType(streamType:String):Void {
  1210. _streamType = streamType;
  1211. }
  1212. /**
  1213. * Sets the server url for rtmp streams
  1214. * @param server
  1215. */
  1216. public function setServer(server:String):Void {
  1217. _server = server;
  1218. }
  1219. /**
  1220. * To set the video source in case we dont want to start downloading at first so when use tooglePlay the
  1221. * media is loaded automatically
  1222. * @param source
  1223. */
  1224. public function setSource(source):Void {
  1225. _mediaSource = source;
  1226. }
  1227. /**
  1228. * Changes the current volume
  1229. * @param volume
  1230. */
  1231. public function setVolume(volume:Float):Void {
  1232. var soundTransform:SoundTransform = new SoundTransform();
  1233. _volume = volume;
  1234. soundTransform.volume = volume;
  1235. if (!_firstLoad) {
  1236. if (_streamType == StreamType.YOUTUBE) {
  1237. Reflect.field(_youtubeLoader.content, "setVolume")(soundTransform.volume * 100);
  1238. }
  1239. else if (_type == InputType.VIDEO || _streamType == StreamType.RTMP) {
  1240. _stream.soundTransform = soundTransform;
  1241. }
  1242. else if (_type == InputType.AUDIO) {
  1243. _soundChannel.soundTransform = soundTransform;
  1244. }
  1245. }
  1246. //Store volume into user settings
  1247. _userSettings.setVolume(_volume);
  1248. callEvents(PlayerEvents.VOLUME_CHANGE);
  1249. }
  1250. /**
  1251. * Changes the buffer time for local and pseudo streaming
  1252. * @param time in seconds
  1253. */
  1254. public function setBufferTime(time:Float):Void {
  1255. if (time > 0) {
  1256. _bufferTime = time;
  1257. }
  1258. }
  1259. /**
  1260. * Show/Hide the Loader
  1261. * @param true / false
  1262. */
  1263. public function setLoader(val:Bool):Void {
  1264. _showLoader = val;
  1265. }
  1266. /**
  1267. * Changes the aspec ratio of current playing media and resizes video player
  1268. * @param aspectRatio new aspect ratio value
  1269. */
  1270. public function setAspectRatio(aspectRatio:Float):Void {
  1271. _aspectRatio = aspectRatio;
  1272. switch(_aspectRatio)
  1273. {
  1274. case 0.0:
  1275. _currentAspectRatio = "original";
  1276. case AspectRatio._1_1:
  1277. _currentAspectRatio = "1:1";
  1278. case AspectRatio._3_2:
  1279. _currentAspectRatio = "3:2";
  1280. case AspectRatio._4_3:
  1281. _currentAspectRatio = "4:3";
  1282. case AspectRatio._5_4:
  1283. _currentAspectRatio = "5:4";
  1284. case AspectRatio._14_9:
  1285. _currentAspectRatio = "14:9";
  1286. case AspectRatio._14_10:
  1287. _currentAspectRatio = "14:10";
  1288. case AspectRatio._16_9:
  1289. _currentAspectRatio = "16:9";
  1290. case AspectRatio._16_10:
  1291. _currentAspectRatio = "16:10";
  1292. }
  1293. resizeAndCenterPlayer();
  1294. //Store aspect ratio into user settings
  1295. _userSettings.setAspectRatio(_aspectRatio);
  1296. }
  1297. /**
  1298. * Enable or disable hardware scaling
  1299. * @param value true to enable false to disable
  1300. */
  1301. public function setHardwareScaling(value:Bool):Void {
  1302. _useHardWareScaling = value;
  1303. }
  1304. //}
  1305. //{Getters
  1306. /**
  1307. * Gets the volume amount 0.0 to 1.0
  1308. * @return
  1309. */
  1310. public function getVolume():Float {
  1311. return _volume;
  1312. }
  1313. /**
  1314. * The current aspect ratio of the loaded Player
  1315. * @return
  1316. */
  1317. public function getAspectRatio():Float {
  1318. return _aspectRatio;
  1319. }
  1320. /**
  1321. * The current aspect ratio of the loaded Player in string format
  1322. * @return
  1323. */
  1324. public function getAspectRatioString():String {
  1325. return _currentAspectRatio;
  1326. }
  1327. /**
  1328. * Original aspect ratio of the video
  1329. * @return original aspect ratio
  1330. */
  1331. public function getOriginalAspectRatio():Float {
  1332. return _originalAspectRatio;
  1333. }
  1334. /**
  1335. * Total duration time of the loaded media
  1336. * @return time in seconds
  1337. */
  1338. public function getDuration():Float {
  1339. return _mediaDuration;
  1340. }
  1341. /**
  1342. * The time in seconds where the player started downloading
  1343. * @return time in seconds
  1344. */
  1345. public function getStartTime():Float {
  1346. return _startTime;
  1347. }
  1348. /**
  1349. * The stream associated with the player
  1350. * @return netstream object
  1351. */
  1352. public function getNetStream():NetStream {
  1353. return _stream;
  1354. }
  1355. /**
  1356. * Video object associated to the player
  1357. * @return video object for further manipulation
  1358. */
  1359. public function getVideo():Video {
  1360. return _video;
  1361. }
  1362. /**
  1363. * Sound object associated to the player
  1364. * @return sound object for further manipulation
  1365. */
  1366. public function getSound():Sound {
  1367. return _sound;
  1368. }
  1369. /**
  1370. * The id3 info of sound object
  1371. * @return
  1372. */
  1373. public function getId3Info():ID3Info {
  1374. return _id3Info;
  1375. }
  1376. /**
  1377. * The current sound state
  1378. * @return true if mute otherwise false
  1379. */
  1380. public function getMute():Bool {
  1381. return _soundMuted;
  1382. }
  1383. /**
  1384. * The amount of total bytes
  1385. * @return amount of bytes
  1386. */
  1387. public function getBytesTotal():Float {
  1388. var bytesTotal:Float = 0;
  1389. if (_streamType == StreamTyp