feat(ws): barebones SetPlayhead event
This commit is contained in:
parent
5f81ed1756
commit
728f2d67d0
|
|
@ -5,14 +5,17 @@
|
|||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="8a64704d-5500-41a6-aa4c-e275933fc58c" name="Changes" comment="">
|
||||
<change beforePath="$PROJECT_DIR$/../.vscode/settings.json" beforeDir="false" afterPath="$PROJECT_DIR$/../.vscode/settings.json" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/cmd/watchtogether/build.sh" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/../frontend/src/interfaces/SocketEvents.ts" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/cmd/watchtogether/main.go" beforeDir="false" afterPath="$PROJECT_DIR$/cmd/watchtogether/main.go" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/internal/ws/handlers.go" beforeDir="false" afterPath="$PROJECT_DIR$/internal/ws/handlers.go" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/../frontend/package.json" beforeDir="false" afterPath="$PROJECT_DIR$/../frontend/package.json" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/../frontend/src/hooks/useWS.ts" beforeDir="false" afterPath="$PROJECT_DIR$/../frontend/src/hooks/useWS.ts" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/internal/ws/hub.go" beforeDir="false" afterPath="$PROJECT_DIR$/internal/ws/hub.go" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/internal/ws/message.go" beforeDir="false" afterPath="$PROJECT_DIR$/internal/ws/message.go" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/../frontend/src/components/Container.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/../frontend/src/components/Container.tsx" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/../frontend/src/components/Player.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/../frontend/src/components/Player.tsx" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/../frontend/src/interfaces/Identity.ts" beforeDir="false" afterPath="$PROJECT_DIR$/../frontend/src/interfaces/Identity.ts" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/../frontend/src/pages/player.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/../frontend/src/pages/player.tsx" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/../frontend/src/ws/websocket.ts" beforeDir="false" afterPath="$PROJECT_DIR$/../frontend/src/ws/websocket.ts" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/../frontend/yarn.lock" beforeDir="false" afterPath="$PROJECT_DIR$/../frontend/yarn.lock" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
#!/bin/bash
|
||||
VERSION=v1.0.0
|
||||
COMMIT_HASH=$(git rev-parse --short HEAD)
|
||||
ENVIRONMENT=$ENV
|
||||
BUILDSTRING="$VERSION-$COMMIT_HASH-$ENVIRONMENT"
|
||||
echo The environment is "$ENVIRONMENT"
|
||||
echo Building watch together backend "$VERSION-$COMMIT_HASH"
|
||||
if [[ "$ENVIRONMENT" == "dev" ]]; then
|
||||
go build -gcflags="all=-N -l" -ldflags "-X github.com/qpixel/watchtogether/cmd/watchtogether/main.VERSION=${BUILDSTRING} -X github.com/qpixel/watchtogether/cmd/watchtogether/main.ENVIRONMENT=${ENVIRONMENT}";
|
||||
else
|
||||
go build -ldflags "-X github.com/qpixel/watchtogether/cmd/watchtogether/main.VERSION=${BUILDSTRING} -X github.com/ubergeek77/uberbot/v2/core.ENVIRONMENT=${ENVIRONMENT}";
|
||||
fi
|
||||
|
|
@ -10,6 +10,11 @@ import (
|
|||
|
||||
var log = tlog.NewTaggedLogger("Logger", tlog.NewColor("38;5;111"))
|
||||
|
||||
var (
|
||||
VERSION string
|
||||
ENVIRONMENT string
|
||||
)
|
||||
|
||||
func main() {
|
||||
r := mux.NewRouter()
|
||||
hub := ws.NewHub()
|
||||
|
|
@ -47,7 +52,8 @@ func main() {
|
|||
}
|
||||
return
|
||||
})
|
||||
|
||||
log.Infof("starting backend")
|
||||
log.Infof("running version %s. environment: %s", VERSION, ENVIRONMENT)
|
||||
err := http.ListenAndServe(":8080", r)
|
||||
if err != nil {
|
||||
log.Errorf("%s", err.Error())
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@ func handleIdentifyEvent(message *Message) {
|
|||
Type: Identify,
|
||||
Data: map[string]interface{}{
|
||||
"admin": true,
|
||||
"playlist": "http://cdnapi.kaltura.com/p/1878761/sp/187876100/playManifest/entryId/1_usagz19w/flavorIds/1_5spqkazq,1_nslowvhp,1_boih5aji,1_qahc37ag/format/applehttp/protocol/http/a.m3u8",
|
||||
"playlist": "http://localhost:8081/BelleOpening.m3u8",
|
||||
"controller": true,
|
||||
"playhead": 0,
|
||||
"user": d["user"],
|
||||
},
|
||||
|
|
@ -42,5 +43,21 @@ func handleGetPlayhead(message *Message) {
|
|||
}
|
||||
|
||||
func handleSetPlayhead(message *Message) {
|
||||
|
||||
d := message.Data.(map[string]interface{})
|
||||
m := Message{
|
||||
MessageData: MessageData{
|
||||
Type: SetPlayhead,
|
||||
Data: map[string]interface{}{
|
||||
"playhead": d["playhead"],
|
||||
"paused": d["paused"],
|
||||
},
|
||||
},
|
||||
}
|
||||
log.Infof("Received SetPlayhead event. playhead is at %s", d["playhead"])
|
||||
for client := range message.Client.hub.Clients {
|
||||
if client == message.Client {
|
||||
continue
|
||||
}
|
||||
client.send <- m.SerializeMessage().Data
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,9 +30,9 @@ func (h *Hub) handleMessage(rm RawMessage) {
|
|||
handleIdentifyEvent(&m)
|
||||
case Ping:
|
||||
handlePingEvent(&m)
|
||||
case Position:
|
||||
case GetPlayhead:
|
||||
handleGetPlayhead(&m)
|
||||
case SetPosition:
|
||||
case SetPlayhead:
|
||||
handleSetPlayhead(&m)
|
||||
default:
|
||||
return
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@ const (
|
|||
Ping MessageTypes = iota
|
||||
Pong
|
||||
Identify
|
||||
Position
|
||||
SetPosition
|
||||
GetPlayhead
|
||||
SetPlayhead
|
||||
)
|
||||
|
||||
type MessageData struct {
|
||||
|
|
|
|||
|
|
@ -1,19 +1,23 @@
|
|||
import { Flex, useColorMode, FlexProps } from '@chakra-ui/react'
|
||||
import React, { FC } from "react";
|
||||
import { Flex, useColorMode, FlexProps } from "@chakra-ui/react";
|
||||
|
||||
export const Container = (props: FlexProps) => {
|
||||
const { colorMode } = useColorMode()
|
||||
export const Container: FC<FlexProps> = (props: FlexProps) => {
|
||||
const { colorMode } = useColorMode();
|
||||
|
||||
const bgColor = { light: 'gray.50', dark: 'gray.900' }
|
||||
const bgColor = { light: "gray.50", dark: "gray.900" };
|
||||
|
||||
const color = { light: 'black', dark: 'white' }
|
||||
const color = { light: "black", dark: "white" };
|
||||
return (
|
||||
<Flex
|
||||
direction="column"
|
||||
alignItems="center"
|
||||
justifyContent="flex-start"
|
||||
bg={bgColor[colorMode]}
|
||||
color={color[colorMode]}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
Container.defaultProps = {
|
||||
alignItems: "center",
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,15 +1,90 @@
|
|||
import React, { FC } from "react";
|
||||
import { Box, css } from "@chakra-ui/react";
|
||||
import React, { FC, useRef, useState } from "react";
|
||||
import ReactPlayer, { Config, ReactPlayerProps } from "react-player";
|
||||
import { MessageTypes } from "../interfaces/IMessage";
|
||||
import Message from "../util/Message";
|
||||
import MessageUtil from "../util/MessageUtil";
|
||||
import PlayerSocket from "../ws/websocket";
|
||||
|
||||
type PlayerProps = { id: string } & ReactPlayerProps;
|
||||
type PlayerProps = {
|
||||
id: string;
|
||||
socket: PlayerSocket;
|
||||
} & ReactPlayerProps;
|
||||
|
||||
interface ProgressProps {
|
||||
played: number;
|
||||
playedSeconds: number;
|
||||
loaded: number;
|
||||
loadedSeconds: number;
|
||||
}
|
||||
|
||||
const Player: FC<PlayerProps> = (props) => {
|
||||
const playerRef = useRef<ReactPlayer>(null);
|
||||
const [paused, setPaused] = useState<boolean>(false);
|
||||
const { socket } = props;
|
||||
const config: Config = {
|
||||
file: {
|
||||
forceHLS: true,
|
||||
},
|
||||
};
|
||||
return <ReactPlayer url={props.id} config={config} {...props} />;
|
||||
const onProgress = (state: ProgressProps) => {
|
||||
if (paused) {
|
||||
socket?.send(
|
||||
MessageUtil.encode(
|
||||
new Message(MessageTypes.SetPlayhead, {
|
||||
playhead: state.playedSeconds,
|
||||
paused: true,
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
socket?.send(
|
||||
MessageUtil.encode(
|
||||
new Message(MessageTypes.SetPlayhead, {
|
||||
playhead: state.playedSeconds,
|
||||
paused: false,
|
||||
})
|
||||
)
|
||||
);
|
||||
};
|
||||
const onPause = () => {
|
||||
setPaused(true);
|
||||
socket?.send(
|
||||
MessageUtil.encode(
|
||||
new Message(MessageTypes.SetPlayhead, {
|
||||
playhead: playerRef.current.getCurrentTime(),
|
||||
paused: true,
|
||||
})
|
||||
)
|
||||
);
|
||||
};
|
||||
const onPlay = () => {
|
||||
setPaused(false);
|
||||
socket?.send(
|
||||
MessageUtil.encode(
|
||||
new Message(MessageTypes.SetPlayhead, {
|
||||
playhead: playerRef.current.getCurrentTime(),
|
||||
paused: false,
|
||||
})
|
||||
)
|
||||
);
|
||||
};
|
||||
return (
|
||||
<Box height="100vh" width="100vw">
|
||||
<ReactPlayer
|
||||
url={props.id}
|
||||
width="100%"
|
||||
height="100%"
|
||||
config={config}
|
||||
controls
|
||||
onPlay={onPlay}
|
||||
onPause={onPause}
|
||||
onProgress={onProgress}
|
||||
ref={playerRef}
|
||||
{...props}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default Player;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
import IUser from "./IUser";
|
||||
|
||||
interface IdentityData {
|
||||
admin?: boolean;
|
||||
controller?: boolean;
|
||||
clientID?: string;
|
||||
playlist?: string;
|
||||
playHead?: number;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
enum SocketEvents {
|
||||
Identify = "Identify",
|
||||
}
|
||||
|
||||
export default SocketEvents;
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
import { Socket } from "dgram";
|
||||
import { GetServerSideProps, NextPage } from "next";
|
||||
import { User } from "next-auth";
|
||||
import { getSession } from "next-auth/react";
|
||||
|
|
@ -5,36 +6,42 @@ import dynamic from "next/dynamic";
|
|||
import Head from "next/head";
|
||||
import React, { useRef, useState } from "react";
|
||||
import ReactPlayer from "react-player";
|
||||
import { BaseReactPlayerProps } from "react-player/base";
|
||||
import { Container } from "../components/Container";
|
||||
import useWS from "../hooks/useWS";
|
||||
import IdentityData from "../interfaces/Identity";
|
||||
import { MessageTypes } from "../interfaces/IMessage";
|
||||
import SocketEvents from "../interfaces/SocketEvents";
|
||||
import isBrowser from "../util/isBrowser";
|
||||
import Message from "../util/Message";
|
||||
import MessageUtil from "../util/MessageUtil";
|
||||
|
||||
const Player = dynamic(() => import("../components/Player"), { ssr: false });
|
||||
|
||||
interface PlayerPageProps {
|
||||
user: User;
|
||||
}
|
||||
// types for the function
|
||||
|
||||
const PlayerPage: NextPage<PlayerPageProps> = ({ user }) => {
|
||||
const playerRef = useRef<ReactPlayer>();
|
||||
// const playerRef = useRef<ReactPlayer>();
|
||||
const socket = useWS({ user });
|
||||
const [id, setID] = useState<string>("");
|
||||
const [identity, setIdentity] = useState<IdentityData>();
|
||||
if (isBrowser() && typeof socket !== "undefined") {
|
||||
socket.emitter.on("Identify", (e: IdentityData) => {
|
||||
socket.emitter.on(SocketEvents.Identify, (e: IdentityData) => {
|
||||
console.log(e);
|
||||
setID(e.playlist);
|
||||
setIdentity(e);
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Watch Together</title>
|
||||
</Head>
|
||||
<Container height="100vh">
|
||||
<Player id={id} ref={playerRef} />
|
||||
<Container height="100vh" background={"#000"}>
|
||||
<Player id={id} socket={socket} />
|
||||
</Container>
|
||||
</>
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in New Issue