track and manage video state

This commit is contained in:
Travis Eden 2017-12-20 18:38:11 -05:00
parent 7ccf6c0a92
commit 6c4a4e593c
10 changed files with 140 additions and 17 deletions

View file

@ -9,7 +9,7 @@ import { makeSelectCostInfoForUri } from "redux/selectors/cost_info";
import { doFetchAvailability } from "redux/actions/availability";
import { doOpenFileInShell } from "redux/actions/file_info";
import { doPurchaseUri, doStartDownload } from "redux/actions/content";
import { setVideoPause } from "redux/actions/video";
import { doPause } from "redux/actions/media";
import FileDownloadLink from "./view";
const select = (state, props) => ({
@ -25,7 +25,7 @@ const perform = dispatch => ({
openInShell: path => dispatch(doOpenFileInShell(path)),
purchaseUri: uri => dispatch(doPurchaseUri(uri)),
restartDownload: (uri, outpoint) => dispatch(doStartDownload(uri, outpoint)),
setVideoPause: val => dispatch(setVideoPause(val)),
doPause: () => dispatch(doPause()),
});
export default connect(select, perform)(FileDownloadLink);

View file

@ -42,12 +42,12 @@ class FileDownloadLink extends React.PureComponent {
purchaseUri,
costInfo,
loading,
setVideoPause,
doPause,
} = this.props;
const openFile = () => {
openInShell(fileInfo.download_path);
setVideoPause(true);
doPause();
};
if (loading || downloading) {

View file

@ -3,7 +3,8 @@ import { connect } from "react-redux";
import { doChangeVolume } from "redux/actions/app";
import { selectVolume } from "redux/selectors/app";
import { doPlayUri, doSetPlayingUri } from "redux/actions/content";
import { setVideoPause } from "redux/actions/video";
import { doPlay, doPause, savePosition } from "redux/actions/media";
// import { setVideoPause } from "redux/actions/video";
import {
makeSelectMetadataForUri,
makeSelectContentTypeForUri,
@ -15,7 +16,11 @@ import {
} from "redux/selectors/file_info";
import { makeSelectCostInfoForUri } from "redux/selectors/cost_info";
import { selectShowNsfw } from "redux/selectors/settings";
import { selectVideoPause } from "redux/selectors/video";
// import { selectVideoPause } from "redux/selectors/video";
import {
selectMediaPaused,
makeSelectMediaPositionForUri,
} from "redux/selectors/media";
import Video from "./view";
import { selectPlayingUri } from "redux/selectors/content";
@ -29,14 +34,18 @@ const select = (state, props) => ({
playingUri: selectPlayingUri(state),
contentType: makeSelectContentTypeForUri(props.uri)(state),
volume: selectVolume(state),
videoPause: selectVideoPause(state),
// videoPause: selectVideoPause(state),
mediaPaused: selectMediaPaused(state),
mediaPosition: makeSelectMediaPositionForUri(props.uri)(state),
});
const perform = dispatch => ({
play: uri => dispatch(doPlayUri(uri)),
cancelPlay: () => dispatch(doSetPlayingUri(null)),
changeVolume: volume => dispatch(doChangeVolume(volume)),
setVideoPause: val => dispatch(setVideoPause(val)),
// setVideoPause: val => dispatch(setVideoPause(val)),
doPlay: () => dispatch(doPlay()),
doPause: (id, position) => dispatch(doPause(id, position)),
});
export default connect(select, perform)(Video);

View file

@ -20,11 +20,10 @@ class VideoPlayer extends React.PureComponent {
this.togglePlayListener = this.togglePlay.bind(this);
}
componentWillReceiveProps(nextProps) {
if (nextProps.videoPause) {
this.refs.media.children[0].pause();
this.props.setVideoPause(false);
}
componentWillReceiveProps(next) {
const el = this.refs.media.children[0];
if (!this.props.paused && next.paused && !el.paused) el.pause();
// if (this.props.paused && !next.paused && el.paused) el.play();
}
componentDidMount() {
@ -35,7 +34,15 @@ class VideoPlayer extends React.PureComponent {
mediaType,
changeVolume,
volume,
mediaId,
position,
} = this.props;
// I'm using a Timeout because I'm not sure where this should happen
if (position > 0) {
setTimeout(() => (mediaElement.currentTime = position), 900);
}
const loadedMetadata = e => {
this.setState({ hasMetadata: true, startedPlaying: true });
this.refs.media.children[0].play();
@ -68,6 +75,11 @@ class VideoPlayer extends React.PureComponent {
document.addEventListener("keydown", this.togglePlayListener);
const mediaElement = this.refs.media.children[0];
if (mediaElement) {
mediaElement.addEventListener("play", () => this.props.doPlay());
mediaElement.addEventListener("pause", () => {
console.log("CURRENT TIME:", mediaElement.currentTime);
this.props.doPause(this.props.mediaId, mediaElement.currentTime);
});
mediaElement.addEventListener("click", this.togglePlayListener);
mediaElement.addEventListener(
"loadedmetadata",
@ -92,7 +104,9 @@ class VideoPlayer extends React.PureComponent {
const mediaElement = this.refs.media.children[0];
if (mediaElement) {
mediaElement.removeEventListener("click", this.togglePlayListener);
//mediaElement.removeEventListener("play"); ??
}
this.props.doPause(this.props.mediaId, mediaElement.currentTime);
}
renderAudio(container, autoplay) {

View file

@ -56,8 +56,10 @@ class Video extends React.PureComponent {
changeVolume,
volume,
uri,
videoPause,
setVideoPause,
doPlay,
doPause,
mediaPaused,
mediaPosition,
} = this.props;
const isPlaying = playingUri === uri;
@ -93,6 +95,9 @@ class Video extends React.PureComponent {
}
const poster = metadata.thumbnail;
const mediaId = uri.split("#")[1];
console.log("mediaId:", mediaId);
return (
<div
className={klasses.join(" ")}
@ -112,8 +117,11 @@ class Video extends React.PureComponent {
downloadCompleted={fileInfo.completed}
changeVolume={changeVolume}
volume={volume}
videoPause={videoPause}
setVideoPause={setVideoPause}
doPlay={doPlay}
doPause={doPause}
mediaId={mediaId}
paused={mediaPaused}
position={mediaPosition}
/>
))}
{!isPlaying && (

View file

@ -167,3 +167,8 @@ export const HAS_FETCHED_SUBSCRIPTIONS = "HAS_FETCHED_SUBSCRIPTIONS";
// Video controls
export const SET_VIDEO_PAUSE = "SET_VIDEO_PAUSE";
// Media controls
export const MEDIA_PLAY = "MEDIA_PLAY";
export const MEDIA_PAUSE = "MEDIA_PAUSE";
export const MEDIA_POSITION = "MEDIA_POSITION";

View file

@ -0,0 +1,31 @@
// @flow
import * as actions from "constants/action_types";
import type { Action, Dispatch } from "redux/reducers/media";
import lbry from "lbry";
export const doPlay = () => (dispatch: Dispatch) =>
dispatch({
type: actions.MEDIA_PLAY,
});
export const doPause = (id: String, position: String) => (
dispatch: Dispatch
) => {
if (id && position) {
dispatch({
type: actions.MEDIA_POSITION,
id,
position,
});
}
dispatch({ type: actions.MEDIA_PAUSE });
};
export const savePosition = (id: String, position: String) => (
dispatch: Dispatch
) =>
dispatch({
type: actions.MEDIA_POSITION,
id,
position,
});

View file

@ -0,0 +1,39 @@
// @flow
import * as actions from "constants/action_types";
import { handleActions } from "util/redux-utils";
export type MediaState = {
paused: Boolean,
positions: Object,
};
export type Action = any;
export type Dispatch = (action: Action) => any;
const defaultState = { paused: true, positions: {} };
export default handleActions(
{
[actions.MEDIA_PLAY]: (state: MediaState, action: Action) => ({
...state,
paused: false,
}),
[actions.MEDIA_PAUSE]: (state: MediaState, action: Action) => ({
...state,
paused: true,
}),
[actions.MEDIA_POSITION]: (state: MediaState, action: Action) => {
const { id, position } = action;
return {
...state,
positions: {
...state.positions,
[id]: position,
},
};
},
},
defaultState
);

View file

@ -0,0 +1,15 @@
import * as settings from "constants/settings";
import { createSelector } from "reselect";
const _selectState = state => state.media || {};
export const selectMediaPaused = createSelector(
_selectState,
state => state.paused
);
export const makeSelectMediaPositionForUri = uri =>
createSelector(_selectState, state => {
const id = uri.split("#")[1];
return state.positions[id] || null;
});

View file

@ -14,6 +14,7 @@ import walletReducer from "redux/reducers/wallet";
import shapeShiftReducer from "redux/reducers/shape_shift";
import subscriptionsReducer from "redux/reducers/subscriptions";
import videoReducer from "redux/reducers/video";
import mediaReducer from "redux/reducers/media";
import { persistStore, autoRehydrate } from "redux-persist";
import createCompressor from "redux-persist-transform-compress";
import createFilter from "redux-persist-transform-filter";
@ -71,6 +72,7 @@ const reducers = combineReducers({
shapeShift: shapeShiftReducer,
subscriptions: subscriptionsReducer,
video: videoReducer,
media: mediaReducer,
});
const bulkThunk = createBulkThunkMiddleware();