diff options
author | Chocobozzz <me@florianbigard.com> | 2022-05-03 11:38:07 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2022-05-03 14:49:15 +0200 |
commit | 26e3e98ff0e222a9fb9226938ac6902af77921bd (patch) | |
tree | 73d1c6f2524e380862d3365f12043fc319d40841 /server/models/video | |
parent | 86c5229b4d726202378ef46854383bcafca22310 (diff) | |
download | PeerTube-26e3e98ff0e222a9fb9226938ac6902af77921bd.tar.gz PeerTube-26e3e98ff0e222a9fb9226938ac6902af77921bd.tar.zst PeerTube-26e3e98ff0e222a9fb9226938ac6902af77921bd.zip |
Support live session in server
Diffstat (limited to 'server/models/video')
-rw-r--r-- | server/models/video/video-live-session.ts | 142 | ||||
-rw-r--r-- | server/models/video/video.ts | 2 |
2 files changed, 143 insertions, 1 deletions
diff --git a/server/models/video/video-live-session.ts b/server/models/video/video-live-session.ts new file mode 100644 index 000000000..2b4cde9f8 --- /dev/null +++ b/server/models/video/video-live-session.ts | |||
@@ -0,0 +1,142 @@ | |||
1 | import { FindOptions } from 'sequelize' | ||
2 | import { AllowNull, BelongsTo, Column, CreatedAt, DataType, ForeignKey, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript' | ||
3 | import { MVideoLiveSession, MVideoLiveSessionReplay } from '@server/types/models' | ||
4 | import { uuidToShort } from '@shared/extra-utils' | ||
5 | import { LiveVideoError, LiveVideoSession } from '@shared/models' | ||
6 | import { AttributesOnly } from '@shared/typescript-utils' | ||
7 | import { VideoModel } from './video' | ||
8 | |||
9 | export enum ScopeNames { | ||
10 | WITH_REPLAY = 'WITH_REPLAY' | ||
11 | } | ||
12 | |||
13 | @Scopes(() => ({ | ||
14 | [ScopeNames.WITH_REPLAY]: { | ||
15 | include: [ | ||
16 | { | ||
17 | model: VideoModel.unscoped(), | ||
18 | as: 'ReplayVideo', | ||
19 | required: false | ||
20 | } | ||
21 | ] | ||
22 | } | ||
23 | })) | ||
24 | @Table({ | ||
25 | tableName: 'videoLiveSession', | ||
26 | indexes: [ | ||
27 | { | ||
28 | fields: [ 'replayVideoId' ], | ||
29 | unique: true | ||
30 | }, | ||
31 | { | ||
32 | fields: [ 'liveVideoId' ] | ||
33 | } | ||
34 | ] | ||
35 | }) | ||
36 | export class VideoLiveSessionModel extends Model<Partial<AttributesOnly<VideoLiveSessionModel>>> { | ||
37 | |||
38 | @CreatedAt | ||
39 | createdAt: Date | ||
40 | |||
41 | @UpdatedAt | ||
42 | updatedAt: Date | ||
43 | |||
44 | @AllowNull(false) | ||
45 | @Column(DataType.DATE) | ||
46 | startDate: Date | ||
47 | |||
48 | @AllowNull(true) | ||
49 | @Column(DataType.DATE) | ||
50 | endDate: Date | ||
51 | |||
52 | @AllowNull(true) | ||
53 | @Column | ||
54 | error: LiveVideoError | ||
55 | |||
56 | @ForeignKey(() => VideoModel) | ||
57 | @Column | ||
58 | replayVideoId: number | ||
59 | |||
60 | @BelongsTo(() => VideoModel, { | ||
61 | foreignKey: { | ||
62 | allowNull: true, | ||
63 | name: 'replayVideoId' | ||
64 | }, | ||
65 | as: 'ReplayVideo', | ||
66 | onDelete: 'set null' | ||
67 | }) | ||
68 | ReplayVideo: VideoModel | ||
69 | |||
70 | @ForeignKey(() => VideoModel) | ||
71 | @Column | ||
72 | liveVideoId: number | ||
73 | |||
74 | @BelongsTo(() => VideoModel, { | ||
75 | foreignKey: { | ||
76 | allowNull: true, | ||
77 | name: 'liveVideoId' | ||
78 | }, | ||
79 | as: 'LiveVideo', | ||
80 | onDelete: 'set null' | ||
81 | }) | ||
82 | LiveVideo: VideoModel | ||
83 | |||
84 | static load (id: number): Promise<MVideoLiveSession> { | ||
85 | return VideoLiveSessionModel.findOne({ | ||
86 | where: { id } | ||
87 | }) | ||
88 | } | ||
89 | |||
90 | static findSessionOfReplay (replayVideoId: number) { | ||
91 | const query = { | ||
92 | where: { | ||
93 | replayVideoId | ||
94 | } | ||
95 | } | ||
96 | |||
97 | return VideoLiveSessionModel.scope(ScopeNames.WITH_REPLAY).findOne(query) | ||
98 | } | ||
99 | |||
100 | static findCurrentSessionOf (videoId: number) { | ||
101 | return VideoLiveSessionModel.findOne({ | ||
102 | where: { | ||
103 | liveVideoId: videoId, | ||
104 | endDate: null | ||
105 | }, | ||
106 | order: [ [ 'startDate', 'DESC' ] ] | ||
107 | }) | ||
108 | } | ||
109 | |||
110 | static listSessionsOfLiveForAPI (options: { videoId: number }) { | ||
111 | const { videoId } = options | ||
112 | |||
113 | const query: FindOptions<VideoLiveSessionModel> = { | ||
114 | where: { | ||
115 | liveVideoId: videoId | ||
116 | }, | ||
117 | order: [ [ 'startDate', 'ASC' ] ] | ||
118 | } | ||
119 | |||
120 | return VideoLiveSessionModel.scope(ScopeNames.WITH_REPLAY).findAll(query) | ||
121 | } | ||
122 | |||
123 | toFormattedJSON (this: MVideoLiveSessionReplay): LiveVideoSession { | ||
124 | const replayVideo = this.ReplayVideo | ||
125 | ? { | ||
126 | id: this.ReplayVideo.id, | ||
127 | uuid: this.ReplayVideo.uuid, | ||
128 | shortUUID: uuidToShort(this.ReplayVideo.uuid) | ||
129 | } | ||
130 | : undefined | ||
131 | |||
132 | return { | ||
133 | id: this.id, | ||
134 | startDate: this.startDate.toISOString(), | ||
135 | endDate: this.endDate | ||
136 | ? this.endDate.toISOString() | ||
137 | : null, | ||
138 | replayVideo, | ||
139 | error: this.error | ||
140 | } | ||
141 | } | ||
142 | } | ||
diff --git a/server/models/video/video.ts b/server/models/video/video.ts index 13d81561a..d216ed47d 100644 --- a/server/models/video/video.ts +++ b/server/models/video/video.ts | |||
@@ -787,7 +787,7 @@ export class VideoModel extends Model<Partial<AttributesOnly<VideoModel>>> { | |||
787 | 787 | ||
788 | logger.info('Stopping live of video %s after video deletion.', instance.uuid) | 788 | logger.info('Stopping live of video %s after video deletion.', instance.uuid) |
789 | 789 | ||
790 | LiveManager.Instance.stopSessionOf(instance.id) | 790 | LiveManager.Instance.stopSessionOf(instance.id, null) |
791 | } | 791 | } |
792 | 792 | ||
793 | @BeforeDestroy | 793 | @BeforeDestroy |