Skip to content

Commit

Permalink
Feat/studio clock (#60)
Browse files Browse the repository at this point in the history
  • Loading branch information
cpvalente authored Dec 13, 2021
1 parent 627cce7 commit 80c2e9a
Show file tree
Hide file tree
Showing 26 changed files with 1,099 additions and 135 deletions.
46 changes: 29 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,18 @@ Once installed and running, ontime starts a background server that is the heart
The app, is used to add / edit your running order in the event list, and running the timers using the Playback Control function.

From here, any device in the same network with a browser is able to render the views as described. This is done by reaching the ontime server at the _default port 4001_ eg: `localhost:4001` or `192.168.1.3:4001`
You can then use the the ontime logo on the top right corner to select the desired view.
You can then use the ontime logo in the top right corner to select the desired view (event in the lower thirds view, where it is hidden).

In case of unnatended machines or automations, it is possible to use different URL to recall individual views
In case of unattended machines or automations, it is possible to use different URL to recall individual views

```
IP.ADDRESS:4001 > Web server default to stage timer view
IP.ADDRESS:4001/speaker > Speaker / Stage timer view
IP.ADDRESS:4001 > Web server default to presenter timer view
IP.ADDRESS:4001/preseter > Presenter / Stage timer view
IP.ADDRESS:4001/sm > Stage Manager / Backstage view
IP.ADDRESS:4001/public > Public / Foyer view
IP.ADDRESS:4001/pip > Picture in Picture view
IP.ADDRESS:4001/lower > Lower Thirds
IP.ADDRESS:4001/studio > Studio Clock
```

More documentation available [here](https://cpvalente.gitbook.io/ontime/)
Expand All @@ -43,43 +44,54 @@ More documentation available [here](https://cpvalente.gitbook.io/ontime/)
- [x] Send live messages to different screen types
- [x] Ability to differentiate between backstage and public data
- [x] Manage delays workflow
- [x] OSC Control and Feedback
- [x] Open Sound Control (OSC) Control and Feedback
- [x] Roll mode: run independently using the system clock
- [x] Import event list from Excel

## Unopinionated
We are not interested in forcing workflows and have made ontime so it is flexible to whichever way you would like to work.
We are not interested in forcing workflows and have made ontime, so it is flexible to whichever way you would like to work.


- [x] You do not need an order list to use the timer. Create an empty event and the OSC API works just the same
- [x] If you want just the info screens, no need to use the timer!
- [x] Dont have or care for a schedule?
- [x] Don't have or care for a schedule?
- [x] a single event with no data is enough to use the OSC API and get going
- [x] use the order list to create a set of quick timers by setting the beggining and start times to 00:00 and 00:10 (**BAM**! 10 minute timer). You can quick recall this with OSC as always
- [x] use the order list to create a set of quick timers by setting the beginning and start times to 00:00 and 00:10 (**BAM**! 10 minute timer). You can quickly recall this with OSC as always

## Integrations and Workflow
The app is being currently developed to a wide user base, from broadcast to entertainment and conference halls.

Taking advantage of the integrations in Ontime, we currently use Ontime with:
- `disguise`: trigger ontime from d3's timeline using the **OSC API**, **render views** using d3's webmodule
- `OBS`: **render views** using the Browser Module
- `QLab`: trigger ontime using **OSC API**
- `Companion`: trigger ontime and manipulate timer using **OSC API**


## Roadmap
### For version 1
Almost reaching a feature set that we can call v1. Before that:
- [ ] Mac OS version
- [ ] Finish Documentation
### Continuing
### Continued development
There are several features planned in the roadmap.
These will be implemented in a development friendly order unless there is user demand to bump any of them.
- [ ] Linux version
- [ ] Headless version (run server only anywhere, configure from a browser locally)
- [ ] Companion integration
- [ ] Companion module
- [ ] Lower Third Manager
- [ ] Note only event
- [ ] URL Aliases (define configurable aliases to ease onsite setup)
- [ ] Logging view
- [ ] Reach Schedule: way to speedup timer to meet a deadline
- [ ] Excel Import
- [ ] vMix integration

### For version 1
Almost reaching a feature set that we can call v1. Before that:
- [ ] Mac OS version

### Issues
The app is still in pre-release and there are a few issues, mainly concerning style.
This will be receiving attention as we near v1 release

#### Style
- [ ] App appears visually broken: Please ensure that windows settings have no display zoom (it is 125% by default)
- [ ] app needs improvement on handling zoomed interfaces
- [ ] App needs improvement on handling zoomed interfaces: Please ensure that windows settings have no display zoom (it is 125% by default)
- [ ] Very long titles might cause interface to shift

# Help
Expand Down
5 changes: 4 additions & 1 deletion client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"react-scripts": "4.0.3",
"socket.io-client": "^4.3.2",
"typeface-open-sans": "^1.1.13",
"use-fit-text": "^2.4.0",
"web-vitals": "^1.0.1"
},
"scripts": {
Expand All @@ -50,5 +51,7 @@
"last 1 safari version"
]
},
"devDependencies": {}
"devDependencies": {
"sass": "^1.44.0"
}
}
19 changes: 12 additions & 7 deletions client/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,22 @@ const Lower = lazy(() =>
);
const Pip = lazy(() => import('features/viewers/production/Pip'));

const StudioClock = lazy(() => import('features/viewers/studio/StudioClock'));

const queryClient = new QueryClient();
// Seemed to cause issues
// broadcastQueryClient({
// queryClient,
// broadcastChannel: 'ontime',
// });

const SSpeaker = withSocket(PresenterView);
const SSpeakerSimple = withSocket(PresenterSimple);
const SPresenter = withSocket(PresenterView);
const SPresenterSimple = withSocket(PresenterSimple);
const SStageManager = withSocket(StageManager);
const SPublic = withSocket(Public);
const SLowerThird = withSocket(Lower);
const SPip = withSocket(Pip);
const SStudio = withSocket(StudioClock);

function App() {
// Handle keyboard shortcuts
Expand Down Expand Up @@ -69,18 +72,20 @@ function App() {
<ErrorBoundary>
<Suspense fallback={null}>
<Switch>
<Route exact path='/' component={SSpeaker} />
<Route exact path='/' component={SPresenter} />
<Route exact path='/sm' component={SStageManager} />
<Route exact path='/speaker' component={SSpeaker} />
<Route exact path='/stage' component={SSpeaker} />
<Route exact path='/speakersimple' component={SSpeakerSimple} />
<Route exact path='/speaker' component={SPresenter} />
<Route exact path='/presenter' component={SPresenter} />
<Route exact path='/stage' component={SPresenter} />
<Route exact path='/presentersimple' component={SPresenterSimple} />
<Route exact path='/editor' component={Editor} />
<Route exact path='/public' component={SPublic} />
<Route exact path='/pip' component={SPip} />
<Route exact path='/studio' component={SStudio} />
{/* Lower cannot have fallback */}
<Route exact path='/lower' component={SLowerThird} />
{/* Send to default if nothing found */}
<Route component={SSpeaker} />
<Route component={SPresenter} />
</Switch>
</Suspense>
</ErrorBoundary>
Expand Down
Binary file added client/src/assets/fonts/digital-7.mono.ttf
Binary file not shown.
27 changes: 21 additions & 6 deletions client/src/common/components/nav/NavLogo.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import PropTypes from "prop-types";
import { Link, Redirect } from 'react-router-dom';
import { Image } from '@chakra-ui/react';
import { AnimatePresence, motion } from 'framer-motion';
import { useState, useEffect, useCallback } from 'react';
import navlogo from 'assets/images/logos/LOGO-72.png';
import style from './NavLogo.module.css';
import style from './NavLogo.module.scss';

export default function NavLogo() {
export default function NavLogo(props) {
const {isHidden} = props;
const [showNav, setShowNav] = useState(false);

const handleClick = () => {
Expand All @@ -30,9 +32,10 @@ export default function NavLogo() {
};
}, [handleKeyPress]);

const baseOpacity = (isHidden) ? 0 : 0.5
return (
<motion.div
initial={{ opacity: 0.5 }}
initial={{ opacity: baseOpacity }}
whileHover={{ opacity: 1 }}
className={style.navContainer}
>
Expand All @@ -51,12 +54,12 @@ export default function NavLogo() {
className={showNav ? style.nav : style.navHidden}
>
<Link
to='/speaker'
to='/presenter'
className={style.navItem}
tabIndex={1}
onKeyDownCapture={() => <Redirect push to='/speaker' />}
onKeyDownCapture={() => <Redirect push to='/presenter' />}
>
Speaker
Presenter
</Link>
<Link
to='/sm'
Expand Down Expand Up @@ -90,9 +93,21 @@ export default function NavLogo() {
>
PIP
</Link>
<Link
to='/studio'
className={style.navItem}
tabIndex={5}
onKeyDownCapture={() => <Redirect push to='/studio' />}
>
Studio Clock
</Link>
</motion.div>
)}
</AnimatePresence>
</motion.div>
);
}

NavLogo.propTypes = {
isHidden: PropTypes.bool,
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
$nav-color: #fff;

.navContainer {
position: absolute;
right: 2vw;
top: 1vw;
display: flex;
flex-direction: column;
align-items: flex-end;
Expand All @@ -23,4 +26,5 @@
background-color: rgba(0, 0, 0, 0.7);
padding: 0.5vh 1vw;
border-radius: 4px;
color: $nav-color;
}
Loading

0 comments on commit 80c2e9a

Please sign in to comment.