6. Thumbnail and Video Streaming fix
This commit is contained in:
parent
204cda6e75
commit
ce92aee238
7 changed files with 82 additions and 39 deletions
|
|
@ -28,7 +28,8 @@
|
|||
"Bash(bash:*)",
|
||||
"Bash(dos2unix:*)",
|
||||
"WebSearch",
|
||||
"WebFetch(domain:ai.google.dev)"
|
||||
"WebFetch(domain:ai.google.dev)",
|
||||
"Bash(xargs:*)"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,10 +68,11 @@ Create the following directories on your server:
|
|||
|
||||
```
|
||||
/var/www/html/lux-studio/
|
||||
├── api/ # Create this directory
|
||||
├── generated_videos/ # Create this directory
|
||||
├── generated_images/ # Create this directory
|
||||
└── uploads/ # Create this directory
|
||||
├── api/ # PHP files go here
|
||||
├── generated_videos/ # Video output (writable)
|
||||
├── generated_images/ # Image output (writable)
|
||||
└── uploads/ # Session uploads (writable)
|
||||
└── sessions/ # Auto-created per user session
|
||||
```
|
||||
|
||||
**Commands to create directories:**
|
||||
|
|
@ -79,9 +80,11 @@ Create the following directories on your server:
|
|||
sudo mkdir -p /var/www/html/lux-studio/api
|
||||
sudo mkdir -p /var/www/html/lux-studio/generated_videos
|
||||
sudo mkdir -p /var/www/html/lux-studio/generated_images
|
||||
sudo mkdir -p /var/www/html/lux-studio/uploads
|
||||
sudo mkdir -p /var/www/html/lux-studio/uploads/sessions
|
||||
```
|
||||
|
||||
**Important**: PHP files use `dirname(__DIR__)` to store uploads/videos at `/var/www/html/lux-studio/` (NOT inside `/api/`). This keeps generated content separate from code.
|
||||
|
||||
---
|
||||
|
||||
## Step 3: Files to Upload
|
||||
|
|
@ -208,6 +211,9 @@ sudo chmod -R 755 assets/
|
|||
sudo chmod -R 755 api/
|
||||
|
||||
# Writable directories for generated content
|
||||
sudo chown -R www-data:www-data generated_videos/
|
||||
sudo chown -R www-data:www-data generated_images/
|
||||
sudo chown -R www-data:www-data uploads/
|
||||
sudo chmod -R 775 generated_videos/
|
||||
sudo chmod -R 775 generated_images/
|
||||
sudo chmod -R 775 uploads/
|
||||
|
|
@ -216,17 +222,31 @@ sudo chmod -R 775 uploads/
|
|||
sudo chmod 640 api/config.php
|
||||
```
|
||||
|
||||
**Note**: The `uploads/sessions/` subdirectories are created automatically by PHP when users start sessions.
|
||||
|
||||
---
|
||||
|
||||
## Step 6: Enable Apache Rewrite Module
|
||||
## Step 6: Apache Configuration
|
||||
|
||||
### 6.1 Check if mod_rewrite is enabled
|
||||
```bash
|
||||
apache2ctl -M | grep rewrite
|
||||
```
|
||||
|
||||
If not enabled:
|
||||
```bash
|
||||
sudo a2enmod rewrite
|
||||
sudo systemctl restart apache2
|
||||
```
|
||||
|
||||
Ensure your Apache virtual host has `AllowOverride All`:
|
||||
### 6.2 Enable AllowOverride for lux-studio
|
||||
|
||||
Edit your Apache site config:
|
||||
```bash
|
||||
sudo nano /etc/apache2/sites-enabled/000-default.conf
|
||||
```
|
||||
|
||||
Add inside the `<VirtualHost>` block:
|
||||
```apache
|
||||
<Directory /var/www/html/lux-studio>
|
||||
AllowOverride All
|
||||
|
|
@ -238,6 +258,8 @@ Then restart Apache:
|
|||
sudo systemctl restart apache2
|
||||
```
|
||||
|
||||
**Note**: This only affects the `/lux-studio/` directory and won't impact other apps on the server.
|
||||
|
||||
---
|
||||
|
||||
## Complete Directory Structure After Deployment
|
||||
|
|
@ -261,11 +283,18 @@ sudo systemctl restart apache2
|
|||
│ ├── webhook_logger.php # Webhook logging
|
||||
│ ├── env_loader.php # Environment loading
|
||||
│ └── config.php # Created on server
|
||||
├── generated_videos/ # Empty, writable
|
||||
├── generated_images/ # Empty, writable
|
||||
└── uploads/ # Empty, writable
|
||||
├── generated_videos/ # Video output (writable, www-data owned)
|
||||
├── generated_images/ # Image output (writable, www-data owned)
|
||||
└── uploads/ # Session data (writable, www-data owned)
|
||||
└── sessions/ # Auto-created per-user session directories
|
||||
└── {session_id}/ # Created automatically
|
||||
└── images/ # User uploaded/generated images
|
||||
```
|
||||
|
||||
**Storage Paths** (configured in PHP files using `dirname(__DIR__)`):
|
||||
- Images: `/var/www/html/lux-studio/uploads/sessions/{session_id}/images/`
|
||||
- Videos: `/var/www/html/lux-studio/generated_videos/`
|
||||
|
||||
---
|
||||
|
||||
## Azure AD Configuration
|
||||
|
|
@ -308,12 +337,14 @@ You have **two separate Azure AD App Registrations**:
|
|||
| Issue | Solution |
|
||||
|-------|----------|
|
||||
| 404 on assets | Verify all files from `dist/` are uploaded, check `base` path in vite.config.js |
|
||||
| 404 on logo | Ensure `LUX_STUDIO_LOGO.svg` exists at `/var/www/html/lux-studio/LUX_STUDIO_LOGO.svg` |
|
||||
| SSO login fails | Verify redirect URI in Azure Portal matches exactly: `https://ai-sandbox.oliver.solutions/lux-studio/` |
|
||||
| SSO uses wrong Client ID | Ensure you built with `npm run build` (uses `.env.production`), not `npm run dev` |
|
||||
| SSO redirect loop | Clear browser localStorage, check Azure AD redirect URI configuration |
|
||||
| API 500 errors | Check PHP logs: `sudo tail -f /var/log/apache2/error.log` |
|
||||
| .htaccess not working | Ensure `mod_rewrite` is enabled and `AllowOverride All` is set |
|
||||
| Generation fails | Check directories exist and are writable by Apache user |
|
||||
| .htaccess not working | Ensure `mod_rewrite` is enabled and `AllowOverride All` is set for lux-studio directory |
|
||||
| Failed to save image | Create `uploads/sessions` directory and set ownership: `sudo mkdir -p /var/www/html/lux-studio/uploads/sessions && sudo chown -R www-data:www-data /var/www/html/lux-studio/uploads` |
|
||||
| Generation fails | Check directories exist and are writable by Apache user (www-data) |
|
||||
|
||||
### SSO Debug Tips
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,16 @@ class VeoVideoAPI {
|
|||
private $baseUrl = 'https://generativelanguage.googleapis.com/v1beta/models';
|
||||
private $model;
|
||||
|
||||
/**
|
||||
* Get API base path for URLs (production-aware)
|
||||
*/
|
||||
private function getApiBasePath() {
|
||||
// Check if we're in production (lux-studio subdirectory)
|
||||
return (isset($_SERVER['REQUEST_URI']) && strpos($_SERVER['REQUEST_URI'], '/lux-studio/') !== false)
|
||||
? '/lux-studio/api'
|
||||
: '/api';
|
||||
}
|
||||
|
||||
// Available models
|
||||
private static $models = [
|
||||
'standard' => 'veo-3.1-generate-preview',
|
||||
|
|
@ -449,7 +459,7 @@ try {
|
|||
'video' => [
|
||||
'filename' => $filename,
|
||||
'mime_type' => $videoData['mime_type'],
|
||||
'url' => '/api/stream_video.php?file=' . urlencode($filename)
|
||||
'url' => $this->getApiBasePath() . '/stream_video.php?file=' . urlencode($filename)
|
||||
]
|
||||
]);
|
||||
} else if ($videoData['type'] === 'uri') {
|
||||
|
|
@ -491,7 +501,7 @@ try {
|
|||
'video' => [
|
||||
'filename' => $filename,
|
||||
'mime_type' => $videoData['mime_type'],
|
||||
'url' => '/api/stream_video.php?file=' . urlencode($filename)
|
||||
'url' => $this->getApiBasePath() . '/stream_video.php?file=' . urlencode($filename)
|
||||
]
|
||||
]);
|
||||
} else {
|
||||
|
|
@ -571,7 +581,7 @@ try {
|
|||
echo json_encode([
|
||||
'success' => true,
|
||||
'video' => [
|
||||
'url' => '/api/stream_video.php?file=' . urlencode($filename),
|
||||
'url' => $this->getApiBasePath() . '/stream_video.php?file=' . urlencode($filename),
|
||||
'filename' => $filename,
|
||||
'mime_type' => 'video/mp4'
|
||||
]
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
frontend/dist/index.html
vendored
2
frontend/dist/index.html
vendored
|
|
@ -5,7 +5,7 @@
|
|||
<link rel="icon" type="image/svg+xml" href="/lux-studio/LUX_STUDIO_LOGO.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Lux Studio - AI Cinematography</title>
|
||||
<script type="module" crossorigin src="/lux-studio/assets/index-CQhyuIyu.js"></script>
|
||||
<script type="module" crossorigin src="/lux-studio/assets/index-5_WjmgQu.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/lux-studio/assets/index-S7O61I6c.css">
|
||||
</head>
|
||||
<body class="bg-slate-950">
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import React, { useRef, useState, useEffect } from 'react';
|
||||
import { Play, Pause, SkipBack, SkipForward, Volume2, VolumeX, Download, Image, Scissors, ChevronLeft, ChevronRight, FolderPlus, Check } from 'lucide-react';
|
||||
import { getApiUrl } from '../utils/api';
|
||||
|
||||
/**
|
||||
* VideoPlayer component with frame extraction capability
|
||||
|
|
@ -15,7 +16,7 @@ const VideoPlayer = ({ src, onFrameExtract, onSaveToProject, className = '', aut
|
|||
|
||||
// Convert old /generated_videos/ URLs to streaming endpoint for seeking support
|
||||
const videoSrc = src?.startsWith('/generated_videos/')
|
||||
? `/api/stream_video.php?file=${encodeURIComponent(src.replace('/generated_videos/', ''))}`
|
||||
? `${getApiUrl('stream_video.php')}?file=${encodeURIComponent(src.replace('/generated_videos/', ''))}`
|
||||
: src;
|
||||
|
||||
const [isPlaying, setIsPlaying] = useState(false);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue