Add HLS.js support and enhance content streaming logic

- Integrated HLS.js version 1.6.15 into the project for improved video streaming capabilities.
- Updated the ContentsController to check for HLS manifest availability and fall back to presigned URLs for original files if not found.
- Enhanced the VideoPlayer component to handle loading and error states more effectively, improving user experience during streaming.
- Refactored content service methods to return detailed streaming information, including HLS and DASH manifest URLs.
This commit is contained in:
Dorian
2026-02-13 00:04:53 +00:00
parent 0da83f461c
commit 7e9a35a963
9 changed files with 706 additions and 262 deletions

View File

@@ -161,25 +161,14 @@ export class PaymentService {
@Cron(CronExpression.EVERY_MINUTE)
async handlePaymentsCron() {
if (
process.env.ENVIRONMENT === 'development' ||
process.env.ENVIRONMENT === 'local'
)
return;
await Promise.all([
this.handlePayment('watch'),
this.handlePayment('rent'),
]);
Logger.log('Payments handled');
}
@Cron(CronExpression.EVERY_DAY_AT_10AM)
async handleDailyPayments() {
if (
process.env.ENVIRONMENT === 'development' ||
process.env.ENVIRONMENT === 'local'
)
return;
await Promise.all([
this.handlePayment('watch', 'daily'),
this.handlePayment('rent', 'daily'),
@@ -188,11 +177,6 @@ export class PaymentService {
@Cron(CronExpression.EVERY_WEEK)
async handleWeeklyPayments() {
if (
process.env.ENVIRONMENT === 'development' ||
process.env.ENVIRONMENT === 'local'
)
return;
await Promise.all([
this.handlePayment('watch', 'weekly'),
this.handlePayment('rent', 'weekly'),
@@ -201,11 +185,6 @@ export class PaymentService {
@Cron(CronExpression.EVERY_1ST_DAY_OF_MONTH_AT_NOON)
async handleMonthlyPayments() {
if (
process.env.ENVIRONMENT === 'development' ||
process.env.ENVIRONMENT === 'local'
)
return;
await Promise.all([
this.handlePayment('watch', 'monthly'),
this.handlePayment('rent', 'monthly'),
@@ -218,9 +197,15 @@ export class PaymentService {
) {
const satoshiRate = await this.provider.getSatoshiRate();
const column = type === 'watch' ? 'pendingRevenue' : 'rentPendingRevenue';
// Rental prices (and therefore rentPendingRevenue) are denominated in
// sats, not USD. Use a 1-sat minimum threshold for rentals instead of
// the USD-based satoshiRate.
const minThreshold = type === 'rent' ? 1 : satoshiRate;
const options: FindManyOptions<Shareholder> = {
where: {
[column]: MoreThanOrEqual(satoshiRate),
[column]: MoreThanOrEqual(minThreshold),
filmmaker: {
paymentMethods: {
type: 'LIGHTNING',
@@ -230,7 +215,7 @@ export class PaymentService {
},
},
order: {
pendingRevenue: 'DESC',
[column]: 'DESC',
},
relations: ['filmmaker', 'filmmaker.paymentMethods'],
take: 5,
@@ -260,18 +245,27 @@ export class PaymentService {
type === 'watch'
? shareholder.pendingRevenue
: shareholder.rentPendingRevenue;
const sats = revenue / satoshiRate;
const rounded = Math.floor(sats);
// Rental revenue is already in sats (rentalPrice is denominated in sats).
// Subscription/watch revenue is in USD and must be converted.
let rounded: number;
let revenueToBeSent: number;
if (type === 'rent') {
rounded = Math.floor(revenue);
revenueToBeSent = rounded; // sats in, sats out
} else {
const sats = revenue / satoshiRate;
rounded = Math.floor(sats);
const missing = sats - rounded;
const missingRevenue = missing * satoshiRate;
revenueToBeSent = revenue - missingRevenue;
}
if (rounded <= 0) {
return;
}
const missing = sats - rounded;
const missingRevenue = missing * satoshiRate;
const revenueToBeSent = revenue - missingRevenue;
const selectedLightningAddress = shareholder.filmmaker.paymentMethods.find(
(method) => method.selected && method.type === 'LIGHTNING',
);