Skip to content

Commit 11c0363

Browse files
authored
⚡️ Video processing fix (#852)
# Pull Request Info ## Description "Refactor: Livepeer Webhook and Session Model Enhancements This pull request refines the Livepeer webhook handling system, focusing on 'asset ready' and 'asset failed' events. Key improvements include: - Updating the Session model to support new propert fields. - Modifying the state object to accurately reflect current asset status. These enhancements boost our system's ability to process Livepeer notifications, ensuring better user interactions. ## Type of change - [x] Code refactor (non-breaking change which fixes an issue) - [x] New feature (non-breaking change which adds functionality) Fixes (#775 ) ## Checklist: - [x] My code follows the style guidelines of this project - [ ] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published
1 parent 268713c commit 11c0363

File tree

4 files changed

+51
-50
lines changed

4 files changed

+51
-50
lines changed

packages/server/src/controllers/index.controller.ts

Lines changed: 34 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,27 @@
1-
import { IStandardResponse, SendApiResponse } from '@utils/api.response';
1+
import { HttpException } from '@exceptions/HttpException';
2+
import { LivepeerEvent } from '@interfaces/livepeer.interface';
3+
import { ClippingStatus } from '@interfaces/session.interface';
4+
import { StateStatus, StateType } from '@interfaces/state.interface';
5+
import SessionService from '@services/session.service';
6+
import StageService from '@services/stage.service';
7+
import StateService from '@services/state.service';
8+
import { type IStandardResponse, SendApiResponse } from '@utils/api.response';
9+
import { updateEventVideoById } from '@utils/firebase';
10+
import { getAsset, getDownloadUrl } from '@utils/livepeer';
11+
import StorageService from '@utils/s3';
12+
import { validateWebhook } from '@utils/validateWebhook';
213
import {
14+
Body,
315
Controller,
16+
FormField,
417
Get,
18+
Header,
19+
Post,
520
Route,
21+
Security,
622
Tags,
7-
Body,
8-
Post,
9-
Header,
1023
UploadedFile,
11-
FormField,
12-
Security,
1324
} from 'tsoa';
14-
import startAITools from '@aitools/main';
15-
import { validateWebhook } from '@utils/validateWebhook';
16-
import StageService from '@services/stage.service';
17-
import { LivepeerEvent } from '@interfaces/livepeer.interface';
18-
import SessionService from '@services/session.service';
19-
import { getAsset, getDownloadUrl } from '@utils/livepeer';
20-
import StateService from '@services/state.service';
21-
import { StateStatus } from '@interfaces/state.interface';
22-
import StorageService from '@utils/s3';
23-
import { HttpException } from '@exceptions/HttpException';
24-
import { updateEventVideoById } from '@utils/firebase';
2525

2626
@Tags('Index')
2727
@Route('')
@@ -96,18 +96,12 @@ export class IndexController extends Controller {
9696

9797
private async assetReady(id: string) {
9898
const asset = await getAsset(id);
99-
const session = await this.sessionService.findOne({
100-
assetId: asset.id,
101-
});
102-
103-
if (!session) {
104-
return SendApiResponse('No session found', null, '400');
105-
}
106-
// const ipfs = await uploadToIpfs(id);
99+
const session = await this.sessionService.findOne({ assetId: asset.id });
100+
if (!session) throw new HttpException(404, 'No session found');
107101
await this.sessionService.update(session._id.toString(), {
108-
// ipfsURI: ipfs,
109102
videoUrl: asset.playbackUrl,
110103
playbackId: asset.playbackId,
104+
clippingStatus: ClippingStatus.completed,
111105
} as any);
112106

113107
if (session.firebaseId && asset.playbackUrl) {
@@ -116,19 +110,14 @@ export class IndexController extends Controller {
116110
mp4Url: await getDownloadUrl(asset.id),
117111
});
118112
}
119-
120-
const state = await this.stateService.getAll({
121-
sessionId: session._id.toString(),
113+
const state = await this.stateService.findOne({
114+
_id: session._id.toString(),
115+
type: StateType.video,
122116
});
123-
124-
if (!state || state.length === 0) {
125-
return SendApiResponse('No state found', null, '400');
126-
}
127-
await this.stateService.update(state[0]._id.toString(), {
117+
if (!state) throw new HttpException(404, 'No state found');
118+
await this.stateService.update(state._id.toString(), {
128119
status: StateStatus.completed,
129120
});
130-
131-
// await startAITools(payload.payload.id);
132121
}
133122

134123
private async assetFailed(id: string) {
@@ -137,20 +126,20 @@ export class IndexController extends Controller {
137126
assetId: asset.id,
138127
});
139128

140-
if (!session) {
141-
throw 'No session found';
142-
}
129+
if (!session) throw new HttpException(404, 'No session found');
143130

144-
const state = await this.stateService.getAll({
131+
const state = await this.stateService.findOne({
145132
sessionId: session._id.toString(),
133+
type: StateType.video,
146134
});
135+
if (!state) throw new HttpException(404, 'No state found');
147136

148-
if (!state || state.length === 0) {
149-
throw 'No state found';
150-
}
137+
await this.sessionService.update(session._id.toString(), {
138+
clippingStatus: ClippingStatus.failed,
139+
} as any);
151140

152-
await this.stateService.update(state[0]._id.toString(), {
153-
status: StateStatus.error,
141+
await this.stateService.update(state._id.toString(), {
142+
status: StateStatus.failed,
154143
});
155144
}
156145
}

packages/server/src/interfaces/session.interface.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { Document, Types } from 'mongoose';
2-
import { ISpeaker } from './speaker.interface';
1+
import type { Document, Types } from 'mongoose';
2+
import type { ISpeaker } from './speaker.interface';
33

44
export interface ISource {
55
streamUrl?: string;
@@ -21,6 +21,12 @@ export enum SessionType {
2121
video = 'video',
2222
}
2323

24+
export enum ClippingStatus {
25+
pending = 'pending',
26+
failed = 'failed',
27+
completed = 'completed',
28+
}
29+
2430
export interface ISession {
2531
_id?: Types.ObjectId;
2632
name: string;
@@ -54,6 +60,7 @@ export interface ISession {
5460
socials?: { name: string; date: number }[];
5561
firebaseId?: string;
5662
talkType?: string;
63+
clippingStatus?: ClippingStatus;
5764
}
5865

5966
export interface ISessionModel extends Omit<ISession, '_id'>, Document {}

packages/server/src/interfaces/state.interface.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Types, Document } from 'mongoose';
1+
import type { Document, Types } from 'mongoose';
22

33
export enum SheetType {
44
gsheet = 'gsheet',
@@ -10,7 +10,7 @@ export enum StateStatus {
1010
completed = 'completed',
1111
canceled = 'canceled',
1212
sync = 'sync',
13-
error = 'error',
13+
failed = 'failed',
1414
}
1515

1616
export enum StateType {

packages/server/src/models/session.model.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
import { ISessionModel, SessionType } from '@interfaces/session.interface';
1+
import {
2+
ClippingStatus,
3+
type ISessionModel,
4+
SessionType,
5+
} from '@interfaces/session.interface';
26
import { Schema, model } from 'mongoose';
37

48
const SessionSchema = new Schema<ISessionModel>(
@@ -59,6 +63,7 @@ const SessionSchema = new Schema<ISessionModel>(
5963
],
6064
firebaseId: { type: String, default: '' },
6165
talkType: { type: String, default: '' },
66+
clippingStatus: { type: String, enum: Object.keys(ClippingStatus) },
6267
},
6368
{
6469
timestamps: true,

0 commit comments

Comments
 (0)