video caption track
This commit is contained in:
@@ -79,3 +79,7 @@ SubCategory.jsx 참고(Home)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
# 자막영상
|
||||||
|
|
||||||
|
ontv4u 검색 후 첫 영상
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import {
|
|||||||
changeAppStatus,
|
changeAppStatus,
|
||||||
getDeviceId,
|
getDeviceId,
|
||||||
getHttpHeaderForServiceRequest,
|
getHttpHeaderForServiceRequest,
|
||||||
|
getSystemSettings,
|
||||||
} from "../actions/commonActions";
|
} from "../actions/commonActions";
|
||||||
import { getAuthenticationCode } from "../actions/deviceActions";
|
import { getAuthenticationCode } from "../actions/deviceActions";
|
||||||
import {
|
import {
|
||||||
@@ -131,10 +132,7 @@ function AppBase(props) {
|
|||||||
}
|
}
|
||||||
dispatch(getDeviceId());
|
dispatch(getDeviceId());
|
||||||
dispatch(getHttpHeaderForServiceRequest());
|
dispatch(getHttpHeaderForServiceRequest());
|
||||||
//todo subscribe
|
dispatch(getSystemSettings());
|
||||||
// dispatch(getSystemSettings());
|
|
||||||
// //get captionEnable
|
|
||||||
// dispatch(getSystemSettings2());
|
|
||||||
// dispatch(getSystemInfo());
|
// dispatch(getSystemInfo());
|
||||||
document.addEventListener("visibilitychange", visibilityChanged);
|
document.addEventListener("visibilitychange", visibilityChanged);
|
||||||
document.addEventListener("webOSRelaunch", handleRelaunchEvent);
|
document.addEventListener("webOSRelaunch", handleRelaunchEvent);
|
||||||
|
|||||||
@@ -57,6 +57,26 @@ export const alertToast = (payload) => (dispatch, getState) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getSystemSettings =
|
||||||
|
() => (dispatch, getState) => {
|
||||||
|
console.log("getSystemSettings ");
|
||||||
|
lunaSend.getSystemSettings({"category":"caption", "keys": ["captionEnable"]},{
|
||||||
|
onSuccess: (res) => {
|
||||||
|
},
|
||||||
|
onFailure: (err) => {
|
||||||
|
|
||||||
|
},
|
||||||
|
onComplete: (res) => {
|
||||||
|
console.log("getSystemSettings onComplete",res);
|
||||||
|
if(res && res.settings){
|
||||||
|
if(typeof res.settings.captionEnable !== 'undefined'){
|
||||||
|
dispatch(changeAppStatus({captionEnable: res.settings.captionEnable}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
export const getHttpHeaderForServiceRequest =
|
export const getHttpHeaderForServiceRequest =
|
||||||
(onComplete) => (dispatch, getState) => {
|
(onComplete) => (dispatch, getState) => {
|
||||||
console.log("getHttpHeaderForServiceRequest ");
|
console.log("getHttpHeaderForServiceRequest ");
|
||||||
|
|||||||
@@ -99,22 +99,31 @@ export const getSubTitle =
|
|||||||
|
|
||||||
dispatch({
|
dispatch({
|
||||||
type: types.GET_SUBTITLE,
|
type: types.GET_SUBTITLE,
|
||||||
payload: response.data.data,
|
payload: {url: showSubtitleUrl, data: response.data.data},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const onFail = (error) => {
|
const onFail = (error) => {
|
||||||
console.error("getSubTitle onFail", error);
|
console.error("getSubTitle onFail", error);
|
||||||
|
dispatch({
|
||||||
|
type: types.GET_SUBTITLE,
|
||||||
|
payload: {url: showSubtitleUrl, data: "Error"},
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
TAxios(
|
if(!getState().play.subTitleBlobs[showSubtitleUrl]){
|
||||||
dispatch,
|
TAxios(
|
||||||
getState,
|
dispatch,
|
||||||
"get",
|
getState,
|
||||||
URLS.SUBTITLE,
|
"get",
|
||||||
{ showSubtitleUrl },
|
URLS.SUBTITLE,
|
||||||
{},
|
{ showSubtitleUrl },
|
||||||
onSuccess,
|
{},
|
||||||
onFail
|
onSuccess,
|
||||||
);
|
onFail
|
||||||
|
);
|
||||||
|
}else{
|
||||||
|
console.log("playActions getSubTitle no Nothing it's exist", showSubtitleUrl);
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
391
com.twin.app.shoptime/src/components/VideoPlayer/Media.js
Normal file
391
com.twin.app.shoptime/src/components/VideoPlayer/Media.js
Normal file
@@ -0,0 +1,391 @@
|
|||||||
|
"use strict";
|
||||||
|
/* eslint-disable */
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.Media = exports.handledMediaEventsMap = exports.getKeyFromSource = exports["default"] = void 0;
|
||||||
|
|
||||||
|
var _dispatcher = require("@enact/core/dispatcher");
|
||||||
|
|
||||||
|
var _handle = require("@enact/core/handle");
|
||||||
|
|
||||||
|
var _propTypes = _interopRequireDefault(require("@enact/core/internal/prop-types"));
|
||||||
|
|
||||||
|
var _propTypes2 = _interopRequireDefault(require("prop-types"));
|
||||||
|
|
||||||
|
var _react = _interopRequireDefault(require("react"));
|
||||||
|
|
||||||
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
||||||
|
|
||||||
|
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
|
||||||
|
|
||||||
|
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
||||||
|
|
||||||
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||||
|
|
||||||
|
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
|
||||||
|
|
||||||
|
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
|
||||||
|
|
||||||
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
|
||||||
|
|
||||||
|
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
|
||||||
|
|
||||||
|
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
|
||||||
|
|
||||||
|
function _possibleConstructorReturn(self, call) { if (call && (typeof call === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
|
||||||
|
|
||||||
|
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
|
||||||
|
|
||||||
|
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
|
||||||
|
|
||||||
|
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a key representing the source node or nodes provided
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* ```
|
||||||
|
* getKeyFromSource('path/file.mp4'); // 'path/file.mp4'
|
||||||
|
* getKeyFromSource(
|
||||||
|
* <source src="path/file.mp4" type="video/mp4" />
|
||||||
|
* ); // 'path/file.mp4'
|
||||||
|
* getKeyFromSource([
|
||||||
|
* <source src="path/file.mp4" type="video/mp4" />,
|
||||||
|
* <source src="path/file.ogg" type="video/ogg" />,
|
||||||
|
* ]); // 'path/file.mp4+path/file.ogg'
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @function
|
||||||
|
* @param {String|Element|Element[]} source URI for a source, `<source>` node, or array of
|
||||||
|
* `<source>` nodes
|
||||||
|
* @returns {String} Key representing sources
|
||||||
|
* @memberof ui/Media
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
var getKeyFromSource = function getKeyFromSource() {
|
||||||
|
var source = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
|
||||||
|
|
||||||
|
if ( /*#__PURE__*/_react["default"].isValidElement(source)) {
|
||||||
|
return _react["default"].Children.toArray(source).filter(function (s) {
|
||||||
|
return !!s;
|
||||||
|
}).map(function (s) {
|
||||||
|
return s.props.src;
|
||||||
|
}).join('+');
|
||||||
|
}
|
||||||
|
|
||||||
|
return String(source);
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Maps standard media event `type` values to React-style callback prop names
|
||||||
|
*
|
||||||
|
* See https://reactjs.org/docs/events.html#media-events
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* {
|
||||||
|
* abort : 'onAbort',
|
||||||
|
* canplay : 'onCanPlay',
|
||||||
|
* canplaythrough : 'onCanPlayThrough',
|
||||||
|
* durationchange : 'onDurationChange',
|
||||||
|
* emptied : 'onEmptied',
|
||||||
|
* encrypted : 'onEncrypted',
|
||||||
|
* ended : 'onEnded',
|
||||||
|
* error : 'onError',
|
||||||
|
* loadeddata : 'onLoadedData',
|
||||||
|
* loadedmetadata : 'onLoadedMetadata',
|
||||||
|
* loadstart : 'onLoadStart',
|
||||||
|
* pause : 'onPause',
|
||||||
|
* play : 'onPlay',
|
||||||
|
* playing : 'onPlaying',
|
||||||
|
* progress : 'onProgress',
|
||||||
|
* ratechange : 'onRateChange',
|
||||||
|
* seeked : 'onSeeked',
|
||||||
|
* seeking : 'onSeeking',
|
||||||
|
* stalled : 'onStalled',
|
||||||
|
* suspend : 'onSuspend',
|
||||||
|
* timeupdate : 'onTimeUpdate',
|
||||||
|
* volumechange : 'onVolumeChange',
|
||||||
|
* waiting : 'onWaiting'
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @typedef {Object} handledMediaEventsMap
|
||||||
|
* @memberof ui/Media
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
exports.getKeyFromSource = getKeyFromSource;
|
||||||
|
var handledMediaEventsMap = {
|
||||||
|
abort: 'onAbort',
|
||||||
|
canplay: 'onCanPlay',
|
||||||
|
canplaythrough: 'onCanPlayThrough',
|
||||||
|
durationchange: 'onDurationChange',
|
||||||
|
emptied: 'onEmptied',
|
||||||
|
encrypted: 'onEncrypted',
|
||||||
|
ended: 'onEnded',
|
||||||
|
error: 'onError',
|
||||||
|
loadeddata: 'onLoadedData',
|
||||||
|
loadedmetadata: 'onLoadedMetadata',
|
||||||
|
loadstart: 'onLoadStart',
|
||||||
|
pause: 'onPause',
|
||||||
|
play: 'onPlay',
|
||||||
|
playing: 'onPlaying',
|
||||||
|
progress: 'onProgress',
|
||||||
|
ratechange: 'onRateChange',
|
||||||
|
seeked: 'onSeeked',
|
||||||
|
seeking: 'onSeeking',
|
||||||
|
stalled: 'onStalled',
|
||||||
|
suspend: 'onSuspend',
|
||||||
|
timeupdate: 'onTimeUpdate',
|
||||||
|
volumechange: 'onVolumeChange',
|
||||||
|
waiting: 'onWaiting'
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* A component representation of HTMLMediaElement.
|
||||||
|
*
|
||||||
|
* @class Media
|
||||||
|
* @memberof ui/Media
|
||||||
|
* @ui
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports.handledMediaEventsMap = handledMediaEventsMap;
|
||||||
|
|
||||||
|
var Media = /*#__PURE__*/function (_React$Component) {
|
||||||
|
_inherits(Media, _React$Component);
|
||||||
|
|
||||||
|
var _super = _createSuper(Media);
|
||||||
|
|
||||||
|
function Media(props) {
|
||||||
|
var _this;
|
||||||
|
|
||||||
|
_classCallCheck(this, Media);
|
||||||
|
|
||||||
|
_this = _super.call(this, props);
|
||||||
|
|
||||||
|
_this.attachCustomMediaEvents = function () {
|
||||||
|
for (var eventName in _this.handledCustomMediaForwards) {
|
||||||
|
(0, _dispatcher.on)(eventName, _this.handledCustomMediaForwards[eventName], _this.media);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_this.detachCustomMediaEvents = function () {
|
||||||
|
for (var eventName in _this.handledCustomMediaForwards) {
|
||||||
|
(0, _dispatcher.off)(eventName, _this.handledCustomMediaForwards[eventName], _this.media);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_this.handleEvent = function (ev) {
|
||||||
|
(0, _handle.forward)('onUpdate', {
|
||||||
|
type: 'onUpdate'
|
||||||
|
}, _this.props); // fetch the forward() we generated earlier, using the event type as a key to find the real event name.
|
||||||
|
|
||||||
|
var fwd = _this.handledMediaForwards[handledMediaEventsMap[ev.type]];
|
||||||
|
|
||||||
|
if (fwd) {
|
||||||
|
fwd(ev, _this.props);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_this.mediaRef = function (node) {
|
||||||
|
_this.media = node;
|
||||||
|
};
|
||||||
|
|
||||||
|
_this.media = null;
|
||||||
|
_this.handledMediaForwards = {};
|
||||||
|
_this.handledMediaEvents = {};
|
||||||
|
_this.handledCustomMediaForwards = {}; // Generate event handling forwarders and a smooth block to pass to <Video>
|
||||||
|
|
||||||
|
for (var key in props.mediaEventsMap) {
|
||||||
|
var eventName = props.mediaEventsMap[key];
|
||||||
|
_this.handledMediaForwards[eventName] = (0, _handle.forward)(eventName);
|
||||||
|
_this.handledMediaEvents[eventName] = _this.handleEvent;
|
||||||
|
} // Generate event handling forwarders for the custom events too
|
||||||
|
|
||||||
|
|
||||||
|
var _loop = function _loop(_eventName) {
|
||||||
|
var propName = props.customMediaEventsMap[_eventName];
|
||||||
|
var forwardEvent = (0, _handle.forward)(propName);
|
||||||
|
|
||||||
|
_this.handledCustomMediaForwards[_eventName] = function (ev) {
|
||||||
|
return forwardEvent(ev, _this.props);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var _eventName in props.customMediaEventsMap) {
|
||||||
|
_loop(_eventName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _this;
|
||||||
|
}
|
||||||
|
|
||||||
|
_createClass(Media, [{
|
||||||
|
key: "componentDidMount",
|
||||||
|
value: function componentDidMount() {
|
||||||
|
this.attachCustomMediaEvents();
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: "componentDidUpdate",
|
||||||
|
value: function componentDidUpdate(_ref) {
|
||||||
|
var prevSource = _ref.source;
|
||||||
|
var source = this.props.source;
|
||||||
|
|
||||||
|
if (getKeyFromSource(source) !== getKeyFromSource(prevSource)) {
|
||||||
|
this.load();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: "componentWillUnmount",
|
||||||
|
value: function componentWillUnmount() {
|
||||||
|
this.detachCustomMediaEvents();
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: "play",
|
||||||
|
value: function play() {
|
||||||
|
return this.media.play();
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: "pause",
|
||||||
|
value: function pause() {
|
||||||
|
this.media.pause();
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: "load",
|
||||||
|
value: function load() {
|
||||||
|
this.media.load();
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: "render",
|
||||||
|
value: function render() {
|
||||||
|
var _this$props = this.props,
|
||||||
|
customMediaEventsMap = _this$props.customMediaEventsMap,
|
||||||
|
Component = _this$props.mediaComponent,
|
||||||
|
source = _this$props.source,
|
||||||
|
track = _this$props.track,
|
||||||
|
rest = _objectWithoutProperties(_this$props, ["customMediaEventsMap", "mediaComponent", "source", "track"]);
|
||||||
|
|
||||||
|
delete rest.mediaEventsMap;
|
||||||
|
delete rest.onUpdate; // Remove the events we manually added so they aren't added twice or fail.
|
||||||
|
|
||||||
|
for (var eventName in customMediaEventsMap) {
|
||||||
|
delete rest[customMediaEventsMap[eventName]];
|
||||||
|
}
|
||||||
|
|
||||||
|
return /*#__PURE__*/_react["default"].createElement(Component, Object.assign({}, rest, this.handledMediaEvents, {
|
||||||
|
ref: this.mediaRef
|
||||||
|
}), source, track);
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: "currentTime",
|
||||||
|
get: function get() {
|
||||||
|
return this.media.currentTime;
|
||||||
|
},
|
||||||
|
set: function set(currentTime) {
|
||||||
|
this.media.currentTime = currentTime;
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: "duration",
|
||||||
|
get: function get() {
|
||||||
|
return this.media.duration;
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: "error",
|
||||||
|
get: function get() {
|
||||||
|
return this.media.networkState === this.media.NETWORK_NO_SOURCE;
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: "loading",
|
||||||
|
get: function get() {
|
||||||
|
return this.media.readyState < this.media.HAVE_ENOUGH_DATA;
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: "paused",
|
||||||
|
get: function get() {
|
||||||
|
return this.media.paused;
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: "playbackRate",
|
||||||
|
get: function get() {
|
||||||
|
return this.media.playbackRate;
|
||||||
|
},
|
||||||
|
set: function set(playbackRate) {
|
||||||
|
this.media.playbackRate = playbackRate;
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: "proportionLoaded",
|
||||||
|
get: function get() {
|
||||||
|
return this.media.buffered.length && this.media.buffered.end(this.media.buffered.length - 1) / this.media.duration;
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: "proportionPlayed",
|
||||||
|
get: function get() {
|
||||||
|
return this.media.currentTime / this.media.duration;
|
||||||
|
}
|
||||||
|
}]);
|
||||||
|
|
||||||
|
return Media;
|
||||||
|
}(_react["default"].Component);
|
||||||
|
|
||||||
|
exports.Media = Media;
|
||||||
|
Media.propTypes =
|
||||||
|
/** @lends ui/Media.Media.prototype */
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* A type of media component.
|
||||||
|
*
|
||||||
|
* @type {String|Component}
|
||||||
|
* @required
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
mediaComponent: _propTypes["default"].renderable.isRequired,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An event map object for custom media events.
|
||||||
|
*
|
||||||
|
* List custom events that aren't standard to React. These will be directly added to the media
|
||||||
|
* element and props matching their name will be executed as callback functions when the event fires.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* ```
|
||||||
|
* {'umsmediainfo': 'onUMSMediaInfo'} // `onUMSMediaInfo` prop function will execute when the `umsmediainfo` event happens
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @type {Object}
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
customMediaEventsMap: _propTypes2["default"].object,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A event map object for media events.
|
||||||
|
*
|
||||||
|
* @type {Object}
|
||||||
|
* @default {@link ui/Media.handledMediaEventsMap}
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
mediaEventsMap: _propTypes2["default"].object,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A function to be run when media updates.
|
||||||
|
*
|
||||||
|
* @type {Function}
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
onUpdate: _propTypes2["default"].func,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Media sources passed as children to `mediaComponent`
|
||||||
|
*
|
||||||
|
* See: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/source
|
||||||
|
*
|
||||||
|
* @type {*}
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
source: _propTypes2["default"].any,
|
||||||
|
track: _propTypes2["default"].any //yhcho
|
||||||
|
};
|
||||||
|
Media.defaultProps = {
|
||||||
|
mediaEventsMap: handledMediaEventsMap
|
||||||
|
};
|
||||||
|
var _default = Media;
|
||||||
|
exports["default"] = _default;
|
||||||
@@ -42,7 +42,7 @@ import Announce from "@enact/ui/AnnounceDecorator/Announce";
|
|||||||
import ComponentOverride from "@enact/ui/ComponentOverride";
|
import ComponentOverride from "@enact/ui/ComponentOverride";
|
||||||
import { FloatingLayerDecorator } from "@enact/ui/FloatingLayer";
|
import { FloatingLayerDecorator } from "@enact/ui/FloatingLayer";
|
||||||
import { FloatingLayerContext } from "@enact/ui/FloatingLayer/FloatingLayerDecorator";
|
import { FloatingLayerContext } from "@enact/ui/FloatingLayer/FloatingLayerDecorator";
|
||||||
import Media from "@enact/ui/Media";
|
import Media from "./Media";
|
||||||
import Slottable from "@enact/ui/Slottable";
|
import Slottable from "@enact/ui/Slottable";
|
||||||
import Touchable from "@enact/ui/Touchable";
|
import Touchable from "@enact/ui/Touchable";
|
||||||
|
|
||||||
@@ -719,6 +719,7 @@ const VideoPlayerBase = class extends React.Component {
|
|||||||
onIntroDisabled: PropTypes.func,
|
onIntroDisabled: PropTypes.func,
|
||||||
modalClassName: PropTypes.any,
|
modalClassName: PropTypes.any,
|
||||||
src: PropTypes.string, //for ReactPlayer
|
src: PropTypes.string, //for ReactPlayer
|
||||||
|
reactPlayerConfig: PropTypes.string, //for ReactPlayer
|
||||||
};
|
};
|
||||||
|
|
||||||
static contextType = FloatingLayerContext;
|
static contextType = FloatingLayerContext;
|
||||||
@@ -2063,6 +2064,7 @@ const VideoPlayerBase = class extends React.Component {
|
|||||||
src,
|
src,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
|
reactPlayerConfig,
|
||||||
...mediaProps
|
...mediaProps
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
@@ -2108,6 +2110,7 @@ const VideoPlayerBase = class extends React.Component {
|
|||||||
mediaProps.width = width;
|
mediaProps.width = width;
|
||||||
mediaProps.height = height;
|
mediaProps.height = height;
|
||||||
mediaProps.videoRef = this.setVideoRef;
|
mediaProps.videoRef = this.setVideoRef;
|
||||||
|
mediaProps.config = reactPlayerConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
const controlsAriaProps = this.getControlsAriaProps();
|
const controlsAriaProps = this.getControlsAriaProps();
|
||||||
|
|||||||
@@ -2,41 +2,6 @@ import appinfo from '../../webos-meta/appinfo.json';
|
|||||||
import * as Config from '../utils/Config';
|
import * as Config from '../utils/Config';
|
||||||
import LS2Request from './LS2Request';
|
import LS2Request from './LS2Request';
|
||||||
|
|
||||||
export const getSystemSettings = (
|
|
||||||
parameters,
|
|
||||||
{ onSuccess, onFailure, onComplete }
|
|
||||||
) => {
|
|
||||||
if (typeof window === "object" && window.PalmSystem) {
|
|
||||||
if (process.env.REACT_APP_MODE === "DEBUG") {
|
|
||||||
console.log("LUNA SEND getSystemSettings");
|
|
||||||
return "Some Hard Coded Mock Data";
|
|
||||||
} else {
|
|
||||||
return new LS2Request().send({
|
|
||||||
service: "luna://com.webos.settingsservice",
|
|
||||||
method: "getSystemSettings",
|
|
||||||
subscribe: true,
|
|
||||||
parameters: parameters,
|
|
||||||
onSuccess,
|
|
||||||
onFailure,
|
|
||||||
onComplete,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else if (typeof window === "object") {
|
|
||||||
const language =
|
|
||||||
typeof window.navigator === "object"
|
|
||||||
? window.navigator.language || window.navigator.userLanguage
|
|
||||||
: "en-US";
|
|
||||||
const res = {
|
|
||||||
settings: {
|
|
||||||
smartServiceCountryCode2: language.split("-")[1],
|
|
||||||
captionEnable: true,
|
|
||||||
},
|
|
||||||
returnValue: true,
|
|
||||||
};
|
|
||||||
onSuccess(res);
|
|
||||||
onComplete(res);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
export const getSystemInfo = (
|
export const getSystemInfo = (
|
||||||
parameters,
|
parameters,
|
||||||
{ onSuccess, onFailure, onComplete }
|
{ onSuccess, onFailure, onComplete }
|
||||||
|
|||||||
@@ -87,3 +87,39 @@ export const getHttpHeaderForServiceRequest = ({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getSystemSettings = (
|
||||||
|
parameters,
|
||||||
|
{ onSuccess, onFailure, onComplete }
|
||||||
|
) => {
|
||||||
|
if (typeof window === "object" && window.PalmSystem) {
|
||||||
|
if (process.env.REACT_APP_MODE === "DEBUG") {
|
||||||
|
console.log("LUNA SEND getSystemSettings");
|
||||||
|
return "Some Hard Coded Mock Data";
|
||||||
|
} else {
|
||||||
|
return new LS2Request().send({
|
||||||
|
service: "luna://com.webos.settingsservice",
|
||||||
|
method: "getSystemSettings",
|
||||||
|
subscribe: true,
|
||||||
|
parameters: parameters,
|
||||||
|
onSuccess,
|
||||||
|
onFailure,
|
||||||
|
onComplete,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else if (typeof window === "object") {
|
||||||
|
const language =
|
||||||
|
typeof window.navigator === "object"
|
||||||
|
? window.navigator.language || window.navigator.userLanguage
|
||||||
|
: "en-US";
|
||||||
|
const res = {
|
||||||
|
settings: {
|
||||||
|
smartServiceCountryCode2: language.split("-")[1],
|
||||||
|
captionEnable: true,
|
||||||
|
},
|
||||||
|
returnValue: true,
|
||||||
|
};
|
||||||
|
onSuccess(res);
|
||||||
|
onComplete(res);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -12,6 +12,7 @@ const initialState = {
|
|||||||
loginUserData: {},
|
loginUserData: {},
|
||||||
toast: false,
|
toast: false,
|
||||||
toastText: null,
|
toastText: null,
|
||||||
|
captionEnable: false
|
||||||
},
|
},
|
||||||
httpHeader: null,
|
httpHeader: null,
|
||||||
isGnbOpened: false,
|
isGnbOpened: false,
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import { types } from '../actions/actionTypes';
|
import { types } from '../actions/actionTypes';
|
||||||
|
|
||||||
const initialState = {};
|
const initialState = {
|
||||||
|
subTitleBlobs: {},
|
||||||
|
};
|
||||||
|
|
||||||
export const playReducer = (state = initialState, action) => {
|
export const playReducer = (state = initialState, action) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
@@ -10,8 +12,13 @@ export const playReducer = (state = initialState, action) => {
|
|||||||
chatData: action.payload.text,
|
chatData: action.payload.text,
|
||||||
};
|
};
|
||||||
case types.GET_SUBTITLE: {
|
case types.GET_SUBTITLE: {
|
||||||
let srtText = action.payload.text;
|
let srtText = action.payload.data?.text;
|
||||||
|
if(!srtText){
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
subTitleBlobs: { ...state.subTitleBlobs, [action.payload.url]: "Error" },
|
||||||
|
};
|
||||||
|
}
|
||||||
var srtRegex =
|
var srtRegex =
|
||||||
/(.*\n)?(\d\d:\d\d:\d\d),(\d\d\d --> \d\d:\d\d:\d\d),(\d\d\d)/g;
|
/(.*\n)?(\d\d:\d\d:\d\d),(\d\d\d --> \d\d:\d\d:\d\d),(\d\d\d)/g;
|
||||||
var vttText = "WEBVTT\n\n" + srtText.replace(srtRegex, "$1$2.$3.$4");
|
var vttText = "WEBVTT\n\n" + srtText.replace(srtRegex, "$1$2.$3.$4");
|
||||||
@@ -20,7 +27,7 @@ export const playReducer = (state = initialState, action) => {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
subTitle: blobUrl,
|
subTitleBlobs: { ...state.subTitleBlobs, [action.payload.url]: blobUrl },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ export const ACTIVE_POPUP = {
|
|||||||
alarmOffPopup: "alarmOffPopup",
|
alarmOffPopup: "alarmOffPopup",
|
||||||
qrPopup: "qrPopup",
|
qrPopup: "qrPopup",
|
||||||
};
|
};
|
||||||
|
export const DEBUG_VIDEO_SUBTITLE_TEST = false;
|
||||||
export const AUTO_SCROLL_DELAY = 600;
|
export const AUTO_SCROLL_DELAY = 600;
|
||||||
export const AUTO_SCROLL_GAP = 20;
|
export const AUTO_SCROLL_GAP = 20;
|
||||||
export const SINGLE = "SINGLE";
|
export const SINGLE = "SINGLE";
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import {
|
|||||||
getSubTitle,
|
getSubTitle,
|
||||||
startVideoPlayer,
|
startVideoPlayer,
|
||||||
} from "../../actions/playActions";
|
} from "../../actions/playActions";
|
||||||
|
import * as Config from "../../utils/Config";
|
||||||
import { MediaControls } from "../../components/MediaPlayer";
|
import { MediaControls } from "../../components/MediaPlayer";
|
||||||
import TButton from "../../components/TButton/TButton";
|
import TButton from "../../components/TButton/TButton";
|
||||||
import TButtonTab, { LIST_TYPE } from "../../components/TButtonTab/TButtonTab";
|
import TButtonTab, { LIST_TYPE } from "../../components/TButtonTab/TButtonTab";
|
||||||
@@ -46,6 +47,7 @@ import FeaturedShowContents from "./PlayerTabContents/FeaturedShowContents";
|
|||||||
import LiveChannelContents from "./PlayerTabContents/LiveChannelContents";
|
import LiveChannelContents from "./PlayerTabContents/LiveChannelContents";
|
||||||
import ShopNowContents from "./PlayerTabContents/ShopNowContents";
|
import ShopNowContents from "./PlayerTabContents/ShopNowContents";
|
||||||
import YouMayLikeContents from "./PlayerTabContents/YouMayLikeContents";
|
import YouMayLikeContents from "./PlayerTabContents/YouMayLikeContents";
|
||||||
|
import dummyVtt from "../../../assets/mock/video.vtt";
|
||||||
|
|
||||||
const SpottableBtn = Spottable("button");
|
const SpottableBtn = Spottable("button");
|
||||||
const Container = SpotlightContainerDecorator(
|
const Container = SpotlightContainerDecorator(
|
||||||
@@ -78,6 +80,7 @@ const PlayerPanel = ({
|
|||||||
const chatData = useSelector((state) => state.play.chatData);
|
const chatData = useSelector((state) => state.play.chatData);
|
||||||
const youmaylikeInfos = useSelector((state) => state.main.youmaylikeInfos);
|
const youmaylikeInfos = useSelector((state) => state.main.youmaylikeInfos);
|
||||||
const showDetailInfo = useSelector((state) => state.main.showDetailInfo);
|
const showDetailInfo = useSelector((state) => state.main.showDetailInfo);
|
||||||
|
const captionEnable = useSelector((state) => state.common.appStatus.captionEnable);
|
||||||
const featuredShowsInfos = useSelector(
|
const featuredShowsInfos = useSelector(
|
||||||
(state) => state.main.featuredShowsInfos
|
(state) => state.main.featuredShowsInfos
|
||||||
);
|
);
|
||||||
@@ -86,7 +89,8 @@ const PlayerPanel = ({
|
|||||||
const showNowInfos = useSelector((state) => state.main.showNowInfo);
|
const showNowInfos = useSelector((state) => state.main.showNowInfo);
|
||||||
const showNowProduct = useSelector((state) => state.main.showNowProduct);
|
const showNowProduct = useSelector((state) => state.main.showNowProduct);
|
||||||
const liveShowInfos = useSelector((state) => state.main.liveShowInfos);
|
const liveShowInfos = useSelector((state) => state.main.liveShowInfos);
|
||||||
const vodSubtitleData = useSelector((state) => state.play.subTitle);
|
//getSubTitle
|
||||||
|
const vodSubtitleData = useSelector((state) => state.play.subTitleBlobs);
|
||||||
const tabList = [
|
const tabList = [
|
||||||
$L("SHOP NOW"),
|
$L("SHOP NOW"),
|
||||||
$L(panelInfo?.shptmBanrTpNm === "LIVE" ? "LIVE CHANNEL" : "FEATURED SHOWS"),
|
$L(panelInfo?.shptmBanrTpNm === "LIVE" ? "LIVE CHANNEL" : "FEATURED SHOWS"),
|
||||||
@@ -234,18 +238,6 @@ const PlayerPanel = ({
|
|||||||
}
|
}
|
||||||
}, [panelInfo, playListInfo]);
|
}, [panelInfo, playListInfo]);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (
|
|
||||||
playListInfo &&
|
|
||||||
playListInfo.length > 0 &&
|
|
||||||
playListInfo[0].showSubtitlUrl
|
|
||||||
) {
|
|
||||||
dispatch(
|
|
||||||
getSubTitle({ showSubtitleUrl: playListInfo[0].showSubtitlUrl })
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}, [dispatch, playListInfo]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!panelInfo) return;
|
if (!panelInfo) return;
|
||||||
|
|
||||||
@@ -357,6 +349,52 @@ const PlayerPanel = ({
|
|||||||
}, [panelInfo, isOnTop]);
|
}, [panelInfo, isOnTop]);
|
||||||
|
|
||||||
delete props.panelInfo;
|
delete props.panelInfo;
|
||||||
|
|
||||||
|
const currentSubtTitleUrl = useMemo(()=>{
|
||||||
|
return playListInfo && playListInfo[selectedIndex]?.showSubtitlUrl;
|
||||||
|
},[playListInfo, selectedIndex]);
|
||||||
|
|
||||||
|
const currentPlayingUrl = useMemo(()=>{
|
||||||
|
// return "https://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_320x180.mp4";
|
||||||
|
return playListInfo && playListInfo[selectedIndex]?.showUrl;
|
||||||
|
},[playListInfo, selectedIndex]);
|
||||||
|
|
||||||
|
const currentSubtitleBlob = useMemo(()=>{
|
||||||
|
if(Config.DEBUG_VIDEO_SUBTITLE_TEST){
|
||||||
|
return dummyVtt;
|
||||||
|
}
|
||||||
|
return vodSubtitleData[currentSubtTitleUrl];
|
||||||
|
},[vodSubtitleData, currentSubtTitleUrl]);
|
||||||
|
|
||||||
|
const isReadyToPlay = useMemo(()=>{
|
||||||
|
if(!currentPlayingUrl){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(!Config.DEBUG_VIDEO_SUBTITLE_TEST && currentSubtTitleUrl && !currentSubtitleBlob){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},[currentPlayingUrl, currentSubtTitleUrl, currentSubtitleBlob]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (currentSubtTitleUrl) {
|
||||||
|
dispatch(getSubTitle({ showSubtitleUrl: currentSubtTitleUrl }));
|
||||||
|
}
|
||||||
|
}, [currentSubtTitleUrl]);
|
||||||
|
|
||||||
|
const reactPlayerSubtitleConfig = useMemo(() => {
|
||||||
|
if(currentSubtitleBlob){
|
||||||
|
return {file: {
|
||||||
|
attributes: {
|
||||||
|
crossOrigin: "true",
|
||||||
|
},
|
||||||
|
tracks: [{kind: 'subtitles', src: currentSubtitleBlob, default: true}],
|
||||||
|
}};
|
||||||
|
}else{
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
},[currentSubtitleBlob]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TPanel
|
<TPanel
|
||||||
isTabActivated={false}
|
isTabActivated={false}
|
||||||
@@ -364,10 +402,12 @@ const PlayerPanel = ({
|
|||||||
className={classNames(
|
className={classNames(
|
||||||
css.videoContainer,
|
css.videoContainer,
|
||||||
panelInfo.modal && css.modal,
|
panelInfo.modal && css.modal,
|
||||||
!isOnTop && css.background
|
!isOnTop && css.background,
|
||||||
|
!captionEnable && css.hideSubtitle
|
||||||
)}
|
)}
|
||||||
handleCancel={onClickBack}
|
handleCancel={onClickBack}
|
||||||
>
|
>
|
||||||
|
{isReadyToPlay &&
|
||||||
<VideoPlayer
|
<VideoPlayer
|
||||||
setApiProvider={getPlayer}
|
setApiProvider={getPlayer}
|
||||||
disabled={panelInfo.modal}
|
disabled={panelInfo.modal}
|
||||||
@@ -380,15 +420,23 @@ const PlayerPanel = ({
|
|||||||
setSelectedIndex={setSelectedIndex} // 선택한 인덱스 Set
|
setSelectedIndex={setSelectedIndex} // 선택한 인덱스 Set
|
||||||
selectedIndex={selectedIndex} // 선택한 인덱스
|
selectedIndex={selectedIndex} // 선택한 인덱스
|
||||||
spotlightDisabled={sideOpen || panelInfo.modal}
|
spotlightDisabled={sideOpen || panelInfo.modal}
|
||||||
src={playListInfo && playListInfo[selectedIndex]?.showUrl}
|
src={currentPlayingUrl}
|
||||||
style={panelInfo.modal ? modalStyle : {}}
|
style={panelInfo.modal ? modalStyle : {}}
|
||||||
modalClassName={panelInfo.modal && panelInfo.modalClassName}
|
modalClassName={panelInfo.modal && panelInfo.modalClassName}
|
||||||
|
reactPlayerConfig={reactPlayerSubtitleConfig}
|
||||||
>
|
>
|
||||||
<source
|
{
|
||||||
src={playListInfo && playListInfo[selectedIndex]?.showUrl}
|
typeof window === "object" && window.PalmSystem &&
|
||||||
type="application/mpegurl"
|
<source
|
||||||
/>
|
src={currentPlayingUrl}
|
||||||
|
type="application/mpegurl"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
{ typeof window === "object" && window.PalmSystem && currentSubtitleBlob &&
|
||||||
|
<track kind="subtitles" src={currentSubtitleBlob} default/>
|
||||||
|
}
|
||||||
</VideoPlayer>
|
</VideoPlayer>
|
||||||
|
}
|
||||||
{playListInfo && playListInfo[selectedIndex]?.orderPhnNo && (
|
{playListInfo && playListInfo[selectedIndex]?.orderPhnNo && (
|
||||||
<VideoOverlayWithPhoneNumber
|
<VideoOverlayWithPhoneNumber
|
||||||
className={css.videoOverlayWithPhoneNumber}
|
className={css.videoOverlayWithPhoneNumber}
|
||||||
|
|||||||
@@ -175,4 +175,9 @@
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&.hideSubtitle{
|
||||||
|
video::cue {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user