mirror of
https://github.com/yattee/yattee.git
synced 2026-02-20 01:39:46 +00:00
Yattee v2 rewrite
This commit is contained in:
158
Yattee/Utilities/DirectMediaHelper.swift
Normal file
158
Yattee/Utilities/DirectMediaHelper.swift
Normal file
@@ -0,0 +1,158 @@
|
||||
//
|
||||
// DirectMediaHelper.swift
|
||||
// Yattee
|
||||
//
|
||||
// Helper for creating Video/Stream objects from direct media URLs.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
/// Helper for handling direct media URLs (mp4, m3u8, etc.) without extraction.
|
||||
enum DirectMediaHelper {
|
||||
/// Provider name for direct media URLs.
|
||||
static let provider = "direct_media"
|
||||
|
||||
// MARK: - Supported Extensions
|
||||
|
||||
/// Video file extensions that can be played directly.
|
||||
static let videoExtensions: Set<String> = [
|
||||
"mp4", "m4v", "mov", "mkv", "avi", "webm", "wmv",
|
||||
"flv", "mpg", "mpeg", "3gp", "ts", "m2ts"
|
||||
]
|
||||
|
||||
/// Audio file extensions that can be played directly.
|
||||
static let audioExtensions: Set<String> = [
|
||||
"mp3", "m4a", "aac", "flac", "wav", "ogg", "opus"
|
||||
]
|
||||
|
||||
/// Streaming format extensions (HLS, DASH).
|
||||
static let streamingExtensions: Set<String> = [
|
||||
"m3u8", "mpd"
|
||||
]
|
||||
|
||||
/// All supported media extensions.
|
||||
static var allExtensions: Set<String> {
|
||||
videoExtensions.union(audioExtensions).union(streamingExtensions)
|
||||
}
|
||||
|
||||
// MARK: - Detection
|
||||
|
||||
/// Checks if the URL points to a direct media file based on extension.
|
||||
static func isDirectMediaURL(_ url: URL) -> Bool {
|
||||
let pathExtension = url.pathExtension.lowercased()
|
||||
return allExtensions.contains(pathExtension)
|
||||
}
|
||||
|
||||
/// Checks if the URL is a streaming format (HLS/DASH).
|
||||
static func isStreamingURL(_ url: URL) -> Bool {
|
||||
let pathExtension = url.pathExtension.lowercased()
|
||||
return streamingExtensions.contains(pathExtension)
|
||||
}
|
||||
|
||||
/// Checks if the URL is an audio-only file.
|
||||
static func isAudioURL(_ url: URL) -> Bool {
|
||||
let pathExtension = url.pathExtension.lowercased()
|
||||
return audioExtensions.contains(pathExtension)
|
||||
}
|
||||
|
||||
// MARK: - Video/Stream Creation
|
||||
|
||||
/// Creates a Video model from a direct media URL.
|
||||
static func createVideo(from url: URL) -> Video {
|
||||
let filename = url.lastPathComponent
|
||||
let title = (filename as NSString).deletingPathExtension
|
||||
let host = url.host ?? "Direct Media"
|
||||
|
||||
return Video(
|
||||
id: VideoID(
|
||||
source: .extracted(extractor: provider, originalURL: url),
|
||||
videoID: url.absoluteString
|
||||
),
|
||||
title: title.isEmpty ? filename : title,
|
||||
description: nil,
|
||||
author: Author(id: provider, name: host, hasRealChannelInfo: false),
|
||||
duration: 0, // Unknown until playback
|
||||
publishedAt: nil,
|
||||
publishedText: nil,
|
||||
viewCount: nil,
|
||||
likeCount: nil,
|
||||
thumbnails: [],
|
||||
isLive: isStreamingURL(url), // Treat HLS/DASH as potentially live
|
||||
isUpcoming: false,
|
||||
scheduledStartTime: nil
|
||||
)
|
||||
}
|
||||
|
||||
/// Creates a Stream from a direct media URL.
|
||||
static func createStream(from url: URL) -> Stream {
|
||||
let pathExtension = url.pathExtension.lowercased()
|
||||
let isAudio = isAudioURL(url)
|
||||
let isStreaming = isStreamingURL(url)
|
||||
|
||||
return Stream(
|
||||
url: url,
|
||||
resolution: isAudio ? nil : .p720, // Default assumption for video
|
||||
format: pathExtension,
|
||||
videoCodec: isAudio ? nil : "unknown",
|
||||
audioCodec: "unknown",
|
||||
bitrate: nil,
|
||||
fileSize: nil,
|
||||
isAudioOnly: isAudio,
|
||||
isLive: isStreaming,
|
||||
mimeType: mimeType(for: pathExtension),
|
||||
audioLanguage: nil,
|
||||
audioTrackName: nil,
|
||||
isOriginalAudio: true,
|
||||
httpHeaders: nil,
|
||||
fps: nil
|
||||
)
|
||||
}
|
||||
|
||||
// MARK: - MIME Type Mapping
|
||||
|
||||
/// Returns the MIME type for a file extension.
|
||||
private static func mimeType(for extension: String) -> String? {
|
||||
switch `extension` {
|
||||
case "mp4", "m4v":
|
||||
return "video/mp4"
|
||||
case "mov":
|
||||
return "video/quicktime"
|
||||
case "mkv":
|
||||
return "video/x-matroska"
|
||||
case "avi":
|
||||
return "video/x-msvideo"
|
||||
case "webm":
|
||||
return "video/webm"
|
||||
case "wmv":
|
||||
return "video/x-ms-wmv"
|
||||
case "flv":
|
||||
return "video/x-flv"
|
||||
case "mpg", "mpeg":
|
||||
return "video/mpeg"
|
||||
case "3gp":
|
||||
return "video/3gpp"
|
||||
case "ts", "m2ts":
|
||||
return "video/mp2t"
|
||||
case "m3u8":
|
||||
return "application/vnd.apple.mpegurl"
|
||||
case "mpd":
|
||||
return "application/dash+xml"
|
||||
case "mp3":
|
||||
return "audio/mpeg"
|
||||
case "m4a":
|
||||
return "audio/mp4"
|
||||
case "aac":
|
||||
return "audio/aac"
|
||||
case "flac":
|
||||
return "audio/flac"
|
||||
case "wav":
|
||||
return "audio/wav"
|
||||
case "ogg":
|
||||
return "audio/ogg"
|
||||
case "opus":
|
||||
return "audio/opus"
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user