add a new TVPlayer component,

add tv episode path to db
This commit is contained in:
lukas 2021-04-22 20:31:36 +02:00
parent c30c193ce0
commit f72a3e5fb4
7 changed files with 181 additions and 43 deletions

View File

@ -40,4 +40,36 @@ func AddTvshowHandlers() {
return jsonify(episodes) return jsonify(episodes)
}) })
var le struct {
ID uint32
}
AddHandler("loadEpisode", TVShowNode, &le, func() []byte {
query := fmt.Sprintf(`
SELECT tvshow_episodes.name, season, tvshow_id, episode, filename, t.foldername
FROM tvshow_episodes
JOIN tvshow t on t.id = tvshow_episodes.tvshow_id
WHERE tvshow_episodes.id=%d`, le.ID)
row := database.QueryRow(query)
var ret struct {
Name string
Season uint8
Episode uint8
TVShowID uint32
Path string
}
var filename string
var foldername string
err := row.Scan(&ret.Name, &ret.Season, &ret.TVShowID, &ret.Episode, &filename, &foldername)
if err != nil {
fmt.Println(err.Error())
return nil
}
ret.Path = foldername + "/" + filename
return jsonify(ret)
})
} }

View File

@ -67,8 +67,8 @@ func insertEpisode(path string, ShowName string) {
} }
query := fmt.Sprintf(` query := fmt.Sprintf(`
INSERT INTO tvshow_episodes (name, season, poster, tvshow_id, episode) INSERT INTO tvshow_episodes (name, season, poster, tvshow_id, episode, filename)
VALUES ('%s', %d, '%s', (SELECT tvshow.id FROM tvshow WHERE tvshow.name='%s'), %d)`, name, season, "", ShowName, episode) VALUES ('%s', %d, '%s', (SELECT tvshow.id FROM tvshow WHERE tvshow.name='%s'), %d, '%s')`, name, season, "", ShowName, episode, path)
err = database.Edit(query) err = database.Edit(query)
if err != nil { if err != nil {
fmt.Println(err.Error()) fmt.Println(err.Error())
@ -100,7 +100,8 @@ func insertShowIfNotExisting(show Show, allShows *[]string) {
} }
// todo load tmdb pic // todo load tmdb pic
query := fmt.Sprintf("INSERT INTO tvshow (name, thumbnail) VALUES ('%s', '%s')", show.Name, "") // currently the foldernamme == name which mustn't necessarily be
query := fmt.Sprintf("INSERT INTO tvshow (name, thumbnail, foldername) VALUES ('%s', '%s', '%s')", show.Name, "", show.Name)
err := database.Edit(query) err := database.Edit(query)
if err != nil { if err != nil {
fmt.Println(err.Error()) fmt.Println(err.Error())

View File

@ -9,12 +9,12 @@ create table if not exists actors
create table if not exists settings create table if not exists settings
( (
video_path varchar(255) null, video_path varchar(255) null,
episode_path varchar(255) null, episode_path varchar(255) null,
password varchar(32) null, password varchar(32) default '-1' null,
mediacenter_name varchar(32) null, mediacenter_name varchar(32) default 'OpenMediaCenter' null,
TMDB_grabbing tinyint null, TMDB_grabbing tinyint null,
DarkMode tinyint default 0 null DarkMode tinyint default 0 null
); );
create table if not exists tags create table if not exists tags
@ -26,10 +26,11 @@ create table if not exists tags
create table if not exists tvshow create table if not exists tvshow
( (
name varchar(100) null, name varchar(100) null,
thumbnail mediumblob null, thumbnail mediumblob null,
id int auto_increment id int auto_increment
primary key primary key,
foldername varchar(100) null
); );
create table if not exists tvshow_episodes create table if not exists tvshow_episodes
@ -40,6 +41,8 @@ create table if not exists tvshow_episodes
season int null, season int null,
poster mediumblob null, poster mediumblob null,
tvshow_id int null, tvshow_id int null,
episode int null,
filename varchar(100) null,
constraint tvshow_episodes_tvshow_id_fk constraint tvshow_episodes_tvshow_id_fk
foreign key (tvshow_id) references tvshow (id) foreign key (tvshow_id) references tvshow (id)
); );
@ -48,14 +51,14 @@ create table if not exists videos
( (
movie_id int auto_increment movie_id int auto_increment
primary key, primary key,
movie_name varchar(200) null, movie_name varchar(200) null,
movie_url varchar(250) null, movie_url varchar(250) null,
thumbnail mediumblob null, thumbnail mediumblob null,
likes int default 0 null, poster mediumblob null,
create_date datetime default CURRENT_TIMESTAMP null, likes int default 0 null,
quality int null, quality int null,
length int null comment 'in seconds', length int null comment 'in seconds',
poster mediumblob null create_date datetime default current_timestamp() null
); );
create table if not exists actors_videos create table if not exists actors_videos

View File

@ -18,6 +18,7 @@ import ActorPage from './pages/ActorPage/ActorPage';
import {SettingsTypes} from './types/ApiTypes'; import {SettingsTypes} from './types/ApiTypes';
import AuthenticationPage from './pages/AuthenticationPage/AuthenticationPage'; import AuthenticationPage from './pages/AuthenticationPage/AuthenticationPage';
import TVShowPage from './pages/TVShowPage/TVShowPage'; import TVShowPage from './pages/TVShowPage/TVShowPage';
import TVPlayer from './pages/TVShowPage/TVPlayer';
interface state { interface state {
password: boolean | null; // null if uninitialized - true if pwd needed false if not needed password: boolean | null; // null if uninitialized - true if pwd needed false if not needed
@ -172,6 +173,9 @@ class App extends React.Component<{}, state> {
<Route exact path='/player/:id'> <Route exact path='/player/:id'>
<Player /> <Player />
</Route> </Route>
<Route exact path='/tvplayer/:id'>
<TVPlayer />
</Route>
<Route exact path='/actors'> <Route exact path='/actors'>
<ActorOverviewPage /> <ActorOverviewPage />
</Route> </Route>

View File

@ -15,14 +15,14 @@ import ActorTile from '../../elements/ActorTile/ActorTile';
import {withRouter} from 'react-router-dom'; import {withRouter} from 'react-router-dom';
import {APINode, callAPI} from '../../utils/Api'; import {APINode, callAPI} from '../../utils/Api';
import {RouteComponentProps} from 'react-router'; import {RouteComponentProps} from 'react-router';
import {GeneralSuccess} from '../../types/GeneralTypes'; import {DefaultPlyrOptions, GeneralSuccess} from '../../types/GeneralTypes';
import {ActorType, TagType} from '../../types/VideoTypes'; import {ActorType, TagType} from '../../types/VideoTypes';
import PlyrJS from 'plyr'; import PlyrJS from 'plyr';
import {Button} from '../../elements/GPElements/Button'; import {Button} from '../../elements/GPElements/Button';
import {VideoTypes} from '../../types/ApiTypes'; import {VideoTypes} from '../../types/ApiTypes';
import GlobalInfos from '../../utils/GlobalInfos'; import GlobalInfos from '../../utils/GlobalInfos';
interface myprops extends RouteComponentProps<{id: string}> {} interface Props extends RouteComponentProps<{id: string}> {}
interface mystate { interface mystate {
sources?: PlyrJS.SourceInfo; sources?: PlyrJS.SourceInfo;
@ -42,25 +42,8 @@ interface mystate {
* Player page loads when a video is selected to play and handles the video view * Player page loads when a video is selected to play and handles the video view
* and actions such as tag adding and liking * and actions such as tag adding and liking
*/ */
export class Player extends React.Component<myprops, mystate> { export class Player extends React.Component<Props, mystate> {
options: PlyrJS.Options = { constructor(props: Props) {
controls: [
'play-large', // The large play button in the center
'play', // Play/pause playback
'progress', // The progress bar and scrubber for playback and buffering
'current-time', // The current time of playback
'duration', // The full duration of the media
'mute', // Toggle mute
'volume', // Volume control
'captions', // Toggle captions
'settings', // Settings menu
'airplay', // Airplay (currently Safari only)
'download', // Show a download button with a link to either the current source or a custom URL you specify in your options
'fullscreen' // Toggle fullscreen
]
};
constructor(props: myprops) {
super(props); super(props);
this.state = { this.state = {
@ -94,7 +77,7 @@ export class Player extends React.Component<myprops, mystate> {
<div className={style.videowrapper}> <div className={style.videowrapper}>
{/* video component is added here */} {/* video component is added here */}
{this.state.sources ? ( {this.state.sources ? (
<Plyr style={plyrstyle} source={this.state.sources} options={this.options} /> <Plyr style={plyrstyle} source={this.state.sources} options={DefaultPlyrOptions} />
) : ( ) : (
<div>not loaded yet</div> <div>not loaded yet</div>
)} )}

View File

@ -0,0 +1,97 @@
import * as React from 'react';
import {RouteComponentProps} from 'react-router';
import {withRouter} from 'react-router-dom';
import PageTitle from '../../elements/PageTitle/PageTitle';
import style from '../Player/Player.module.css';
import {Plyr} from 'plyr-react';
import plyrstyle from 'plyr-react/dist/plyr.css';
import {DefaultPlyrOptions} from '../../types/GeneralTypes';
import {APINode, callAPI} from '../../utils/Api';
import GlobalInfos from '../../utils/GlobalInfos';
import PlyrJS from 'plyr';
interface Props extends RouteComponentProps<{id: string}> {}
interface State {
loaded: boolean;
}
interface EpisodeData {
Name: string;
Season: number;
Episode: number;
TVShowID: number;
Path: string;
}
class TVPlayer extends React.Component<Props, State> {
state = {
loaded: false
};
data: EpisodeData | null = null;
componentDidMount(): void {
this.loadVideo();
}
loadVideo(): void {
callAPI(
APINode.TVShow,
{
action: 'loadEpisode',
ID: parseInt(this.props.match.params.id, 10)
},
(data: EpisodeData) => {
console.log(data);
this.data = data;
this.setState({loaded: true});
}
);
}
assemblePlyrObject(): JSX.Element {
if (this.state.loaded && this.data !== null) {
const sources: PlyrJS.SourceInfo = {
type: 'video',
sources: [
{
src:
(process.env.REACT_APP_CUST_BACK_DOMAIN ? process.env.REACT_APP_CUST_BACK_DOMAIN : '') +
GlobalInfos.getTVShowPath() +
this.data.Path,
type: 'video/mp4',
size: 1080
}
],
poster: ''
};
return <Plyr style={plyrstyle} source={sources} options={DefaultPlyrOptions} />;
} else {
return <div>not loaded yet</div>;
}
}
render(): JSX.Element {
return (
<div id='videocontainer'>
<PageTitle title='Watch' subtitle='todo' />
<div className={style.videowrapper}>
{/* video component is added here */}
{this.assemblePlyrObject()}
</div>
<button className={style.closebutton} onClick={(): void => this.closebtn()}>
Close
</button>
</div>
);
}
private closebtn(): void {
this.props.history.goBack();
}
}
export default withRouter(TVPlayer);

View File

@ -1,4 +1,5 @@
import {TagType} from './VideoTypes'; import {TagType} from './VideoTypes';
import PlyrJS from 'plyr';
export interface GeneralSuccess { export interface GeneralSuccess {
result: string; result: string;
@ -14,3 +15,20 @@ export const DefaultTags: TagarrayType = {
lowq: {TagId: 3, TagName: 'lowquality'}, lowq: {TagId: 3, TagName: 'lowquality'},
hd: {TagId: 4, TagName: 'hd'} hd: {TagId: 4, TagName: 'hd'}
}; };
export const DefaultPlyrOptions: PlyrJS.Options = {
controls: [
'play-large', // The large play button in the center
'play', // Play/pause playback
'progress', // The progress bar and scrubber for playback and buffering
'current-time', // The current time of playback
'duration', // The full duration of the media
'mute', // Toggle mute
'volume', // Volume control
'captions', // Toggle captions
'settings', // Settings menu
'airplay', // Airplay (currently Safari only)
'download', // Show a download button with a link to either the current source or a custom URL you specify in your options
'fullscreen' // Toggle fullscreen
]
};