Skip to content

Commit

Permalink
Fixes web player issues on rejoining and ui tweeks to fix streaming
Browse files Browse the repository at this point in the history
  • Loading branch information
robrotheram committed Jan 5, 2024
1 parent a0bc5b6 commit 283ee61
Show file tree
Hide file tree
Showing 13 changed files with 106 additions and 41 deletions.
1 change: 1 addition & 0 deletions pkg/api/webPlayer.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ func (wb *WebPlayer) Play(url string, start int) error {
wb.running = false
return nil
}

func (wb *WebPlayer) Progress() media.MediaDuration {
return wb.progress
}
Expand Down
1 change: 1 addition & 0 deletions pkg/api/websocket.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ func (c *Client) Read() {
_, msg, err := c.socket.ReadMessage()
if err != nil {
fmt.Printf("ERROR decoding %v", err)
c.contoller.RemoveListner(c.id)
return
}
var event controllers.Event
Expand Down
6 changes: 4 additions & 2 deletions pkg/controllers/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,10 @@ func (c *Controller) Update(state PlayerState, user string) {
}

func (c *Controller) Join(player Player, user string) {
c.players.Add(player)
c.Notify(PLAYER_ACTION, user)
if _, ok := c.players.players[player.Type()]; !ok {
c.players.Add(player)
c.Notify(PLAYER_ACTION, user)
}
}

func (c *Controller) Leave(pType PlayerType, user string) {
Expand Down
7 changes: 1 addition & 6 deletions pkg/discord/players/discord.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,12 +139,7 @@ func (player *DiscordPlayer) Play(url string, startTime int) error {
opts.Application = "audio"
opts.PacketLoss = 10
player.startTime = startTime
if err := player.ParseDuration(url); err != nil {
player.progress = media.MediaDuration{
Duration: 0,
Progress: 0,
}
}
player.ParseDuration(url)
encodeSession, err := dca.EncodeFile(url, opts)
if err != nil {
return fmt.Errorf("failed creating an encoding session: %v", err)
Expand Down
16 changes: 13 additions & 3 deletions pkg/media/RadioGarden.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package media

import (
"crypto/tls"
"encoding/json"
"fmt"
"log"
Expand Down Expand Up @@ -39,7 +40,10 @@ type RadioGarden struct {
}

func init() {
RadioGardenClient := &RadioGarden{client: &http.Client{Timeout: 10 * time.Second}}
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
RadioGardenClient := &RadioGarden{client: &http.Client{Timeout: 10 * time.Second, Transport: tr}}
MediaFactory.Register(RadioGardenClient)
}

Expand All @@ -55,7 +59,13 @@ func (radio *RadioGarden) getRadioInfo(id string) (RadioGardenInfo, error) {
}

func (radio *RadioGarden) getAudioURL(id string) string {
return fmt.Sprintf("http://radio.garden/api/ara/content/listen/%s/channel.mp3", id)
resp, err := radio.client.Get(fmt.Sprintf("http://radio.garden/api/ara/content/listen/%s/channel.mp3", id))
if err != nil {
return fmt.Sprintf("http://radio.garden/api/ara/content/listen/%s/channel.mp3", id)
}
// Your magic function. The Request in the Response is the last URL the
// client tried to access.
return resp.Request.URL.String()
}

func (radio *RadioGarden) getIDFromURL(targetUrl string) string {
Expand All @@ -80,7 +90,7 @@ func (radio *RadioGarden) GetMedia(url string, username string) ([]Media, error)
Type: VIDEO_TYPE_RG,
Title: info.Data.Title,
Progress: MediaDuration{
Duration: 0,
Duration: -1,
},
Thumbnail: "https://play-lh.googleusercontent.com/07lewhVI4GklVBi_ehhOXxmB_bPaWWTiyqHAlQP6VsYD7h9R4d8hskNAy4SCOx0leNx-=s180",
AudioUrl: audioUrl,
Expand Down
30 changes: 17 additions & 13 deletions pkg/media/Youtube.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,22 +146,15 @@ func (yt *Youtube) GetMedia(url string, username string) ([]Media, error) {

if err == nil {
video := Media{
ID: ksuid.New().String(),
Url: url,
User: username,
Type: isLive(ytVideo),
Title: ytVideo.Title,
Progress: MediaDuration{
Duration: ytVideo.Duration,
},
ID: ksuid.New().String(),
Url: url,
User: username,
Type: isLive(ytVideo),
Title: ytVideo.Title,
Progress: getDuration(ytVideo),
Thumbnail: ytVideo.Thumbnails[0].URL,
ChannelName: ytVideo.Author,
}
// audio, err := yt.GetAudioUrl(url)
// if err != nil {
// return []Media{}, err
// }
// video.AudioUrl = audio
return []Media{video}, nil
}
return []Media{}, fmt.Errorf("Unable find valid audio for this url, %v", err)
Expand Down Expand Up @@ -189,3 +182,14 @@ func isLive(yt *youtube.Video) MediaType {
}
return VIDEO_TYPE_YT
}

func getDuration(ytVideo *youtube.Video) MediaDuration {
if len(ytVideo.HLSManifestURL) > 1 {
return MediaDuration{
Duration: -1,
}
}
return MediaDuration{
Duration: ytVideo.Duration,
}
}
10 changes: 10 additions & 0 deletions ui/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-hot-toast": "^2.4.1",
"react-hotkeys-hook": "^4.4.3",
"react-player": "2.13.0",
"react-router-dom": "^6.21.0",
"react-swipeable": "^7.0.1"
Expand Down
2 changes: 1 addition & 1 deletion ui/src/pages/app/components/header.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const Header = ({ state }) => {

export const VideoHeader = ({ state, connection }) => {
return (
<div className=" flex flex-col shadow-head relative shadow-xl" style={{ height: "calc(100vh - 15em )" }}>
<div className=" flex flex-col shadow-head relative shadow-xl" style={{ height: "calc(100vh - 12em )" }}>
<div className='bg-black w-full flex-grow flex flex-col justify-center'>
<VideoPlayer state={state} connection={connection}/>
</div>
Expand Down
27 changes: 18 additions & 9 deletions ui/src/pages/app/components/player.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ const Player = ({ state }) => {
return iso.substring(11, iso.length - 5);
}
const playerProgress = (current, total) => {
if (total === -1){
return 100
}
let pct = current / total * 100
return Math.min(Math.max(pct, 0), 100)
}
Expand Down Expand Up @@ -140,7 +143,6 @@ const Player = ({ state }) => {
<div className="flex md:w-48 w-28">
<Switch />
</div>

<button onClick={() => handleShuffle()} data-tooltip-target="tooltip-shuffle" type="button" className="p-2.5 group rounded-full mr-1 focus:outline-none focus:ring-4 focus:ring-gray-600 hover:bg-gray-600">
<svg className="w-5 h-5 text-gray-300 group-hover:text-white" fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" aria-hidden="true"><path d="M403.8 34.4c12-5 25.7-2.2 34.9 6.9l64 64c6 6 9.4 14.1 9.4 22.6s-3.4 16.6-9.4 22.6l-64 64c-9.2 9.2-22.9 11.9-34.9 6.9s-19.8-16.6-19.8-29.6V160H352c-10.1 0-19.6 4.7-25.6 12.8L284 229.3 244 176l31.2-41.6C293.3 110.2 321.8 96 352 96h32V64c0-12.9 7.8-24.6 19.8-29.6zM164 282.7L204 336l-31.2 41.6C154.7 401.8 126.2 416 96 416H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H96c10.1 0 19.6-4.7 25.6-12.8L164 282.7zm274.6 188c-9.2 9.2-22.9 11.9-34.9 6.9s-19.8-16.6-19.8-29.6V416H352c-30.2 0-58.7-14.2-76.8-38.4L121.6 172.8c-6-8.1-15.5-12.8-25.6-12.8H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H96c30.2 0 58.7 14.2 76.8 38.4L326.4 339.2c6 8.1 15.5 12.8 25.6 12.8h32V320c0-12.9 7.8-24.6 19.8-29.6s25.7-2.2 34.9 6.9l64 64c6 6 9.4 14.1 9.4 22.6s-3.4 16.6-9.4 22.6l-64 64z" fill="currentColor" /></svg>
<span className="sr-only">Shuffle video</span>
Expand All @@ -149,7 +151,6 @@ const Player = ({ state }) => {
Shuffle video
<div className="tooltip-arrow" data-popper-arrow></div>
</div>

{state.status === "PLAY" ?
<button onClick={() => handlePause()} data-tooltip-target="tooltip-pause" type="button" className="inline-flex items-center justify-center p-2.5 mx-2 font-medium bg-purple-600 rounded-full hover:bg-purple-700 group focus:ring-4 focus:outline-none focus:ring-purple-800">
<svg className="w-4 h-4 text-white" viewBox="0 0 10 14" fill="currentColor" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
Expand All @@ -165,7 +166,6 @@ const Player = ({ state }) => {
<span className="sr-only">Play video</span>
</button>
}

<button onClick={() => handleSkip()} data-tooltip-target="tooltip-next" type="button" className="p-2.5 group rounded-full mr-1 focus:outline-none focus:ring-4 focus:ring-gray-200 hover:bg-gray-600">
<svg className="w-5 h-5 text-gray-300 group-hover:text-white" fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512" aria-hidden="true"><path d="M52.5 440.6c-9.5 7.9-22.8 9.7-34.1 4.4S0 428.4 0 416V96C0 83.6 7.2 72.3 18.4 67s24.5-3.6 34.1 4.4l192 160L256 241V96c0-17.7 14.3-32 32-32s32 14.3 32 32V416c0 17.7-14.3 32-32 32s-32-14.3-32-32V271l-11.5 9.6-192 160z" fill="currentColor" /></svg>
<span className="sr-only">Next video</span>
Expand All @@ -181,13 +181,22 @@ const Player = ({ state }) => {
</button>
<VolumeControl />
</div>
{state.current.id && <div className="flex items-center justify-between space-x-2">
<span className="text-sm font-medium text-gray-400">{formatTime(state.current.time.progress)}</span>
<div className="w-full rounded-full h-1.5 bg-gray-800">
<div className="bg-purple-600 h-1.5 rounded-full" style={{ "width": `${playerProgress(state.current.time.progress, state.current.time.duration)}%` }}></div>
{state.current.id &&
<div className="flex items-center justify-between space-x-2">
<span className="text-sm font-medium text-gray-400">{formatTime(state.current.time.progress)}</span>
<div className="w-full rounded-full h-1.5 bg-gray-800 ">
<div className="bg-purple-600 h-1.5 rounded-full " style={{ "width": `${playerProgress(state.current.time.progress, state.current.time.duration)}%` }}></div>
</div>
{
state.current.time.duration > -1 ?
<span className="text-sm font-medium text-gray-400">{formatTime(state.current.time.duration)}</span>
:
<div className="text-sm font-medium text-gray-400 inline-flex items-center gap-1">
<span className="w-2 h-2 animate-ping bg-red-800 rounded-full block" /> live
</div>
}
</div>
<span className="text-sm font-medium text-gray-400">{formatTime(state.current.time.duration)}</span>
</div>}
}
</div>
</div>
:
Expand Down
10 changes: 8 additions & 2 deletions ui/src/pages/app/components/videoPlayer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { useContext, useEffect } from 'react';
import ReactPlayer from 'react-player'
import { getRoomId, playVideoController, skipVideoController } from '../watch2gether';
import { VolumeContext } from './providers';
import waveImge from "./wave-signal.svg"

export const VideoPlayer = ({state, connection}) => {
const playerRef = React.useRef(null);
Expand Down Expand Up @@ -33,7 +34,6 @@ export const VideoPlayer = ({state, connection}) => {
Current: s.current
}
}
console.log("SENDING", JSON.stringify(evt))
connection.send(JSON.stringify(evt))
};

Expand All @@ -42,7 +42,7 @@ export const VideoPlayer = ({state, connection}) => {
<div className='w-full flex justify-center' style={{"maxHeight": "650px", height:"100%"}}>
<ReactPlayer
ref={playerRef}
url={state.current.url}
url={state.current.type === "YOUTUBE_LIVE" ? state.current.url : state.current.audio_url}
width='100%'
height='100%'
muted={volume === 0}
Expand All @@ -51,6 +51,12 @@ export const VideoPlayer = ({state, connection}) => {
onEnded={onEnded}
onProgress={handleProgress}
playing={state.status === "PLAY" }
style={{
backgroundImage:`url(${waveImge})`,
backgroundPosition: "center",
backgroundSize: "100% 50%",
backgroundRepeat: "no-repeat"
}}
loop={state.loop}
/>
</div>
Expand Down
23 changes: 23 additions & 0 deletions ui/src/pages/app/components/wave-signal.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 8 additions & 5 deletions ui/src/pages/app/controller.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,10 @@ import Player from "./components/player";
import { addVideoController, getChannelPlaylists, getSocket, updateQueueController, getController, createController } from "./watch2gether";
import { Header, VideoHeader } from "./components/header";
import { useNavigate } from "react-router-dom";
import { NotificationMessages } from "./components/notifications";
import { PlaylistBtn } from "./playlist";
import { PlayerContext } from "./components/providers";
import { Loading } from "./components/loading";
const debug = true
import { useHotkeys } from 'react-hotkeys-hook'

export const AddVideoCtrl = ({ onAddVideo }) => {
const [video, setVideo] = useState("");
Expand Down Expand Up @@ -45,7 +44,11 @@ export const AppController = () => {
const [loading, setLoading] = useState(true)
const [playlists, setPlaylists] = useState([])
const [notificationURL, setNotificationURL] = useState(null)
const [debug, setDebug] = useState(false)

const { showVideo } = useContext(PlayerContext)

useHotkeys('ctrl+shift+b', () => setDebug(!debug), [debug])

const updatePlaylists = async () => {
try {
Expand Down Expand Up @@ -151,10 +154,10 @@ export const AppController = () => {
<PlaylistBtn playlists={playlists} />
</div>

{debug && <div style={{ position: "fixed", top: "150px", width: "50%", background: "white", height: "600px", zIndex: "100" }}>
<pre style={{ overflow: "auto", height: "100%" }}>
{debug && <div className="w-full h-1/3 z-50 p-4">
<pre className="bg-stone-900 text-white rounded-lg p-8 h-full overflow-auto">
<code>
`{JSON.stringify(state, null, 2)}`
{JSON.stringify(state, null, 2)}
</code>
</pre>
</div>}
Expand Down

0 comments on commit 283ee61

Please sign in to comment.