78 lines
1.8 KiB
PHP
78 lines
1.8 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use Illuminate\Database\Eloquent\Casts\Attribute;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Support\Facades\Storage;
|
|
|
|
class Recording extends Model
|
|
{
|
|
/**
|
|
* @var list<string>
|
|
*/
|
|
protected $fillable = [
|
|
'title',
|
|
'original_filename',
|
|
'file_path',
|
|
'duration_seconds',
|
|
'recorded_at',
|
|
'artist',
|
|
'album',
|
|
'file_size_bytes',
|
|
'transcript',
|
|
'transcription_status',
|
|
'transcription_driver',
|
|
'ollama_url',
|
|
'transcribed_at',
|
|
];
|
|
|
|
/**
|
|
* @return array<string, string>
|
|
*/
|
|
protected function casts(): array
|
|
{
|
|
return [
|
|
'recorded_at' => 'datetime',
|
|
'transcribed_at' => 'datetime',
|
|
'duration_seconds' => 'integer',
|
|
'file_size_bytes' => 'integer',
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Human-readable duration (m:ss).
|
|
*/
|
|
protected function durationFormatted(): Attribute
|
|
{
|
|
return Attribute::get(function (): string {
|
|
if ($this->duration_seconds === null) {
|
|
return '—';
|
|
}
|
|
|
|
$minutes = intdiv($this->duration_seconds, 60);
|
|
$seconds = $this->duration_seconds % 60;
|
|
|
|
return sprintf('%d:%02d', $minutes, $seconds);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Absolute filesystem path for the stored audio file.
|
|
*/
|
|
public function absolutePath(): string
|
|
{
|
|
return Storage::disk('local')->path($this->file_path);
|
|
}
|
|
|
|
/**
|
|
* Delete the audio file from storage.
|
|
*/
|
|
public function deleteFile(): void
|
|
{
|
|
if ($this->file_path && Storage::disk('local')->exists($this->file_path)) {
|
|
Storage::disk('local')->delete($this->file_path);
|
|
}
|
|
}
|
|
}
|