I am creating an iOS radio app that performs varied HLS streams. The problem is that some stations broadcast HLS streams containing each audio and video (instance: https://svs.itworkscdn.internet/smcwatarlive/smcwatar/chunks.m3u8), however I wish to:
Extract and play solely the audio observe
Help AirPlay for audio-only streaming
Decrease information utilization by not downloading video content material
Technical Particulars:
iOS 17+
Swift 6
Utilizing AVFoundation for playback
Present implementation makes use of AVPlayer with AVPlayerItem
Present Code Construction:
class StreamPlayer: ObservableObject { @Revealed var isPlaying = false non-public var participant: AVPlayer? non-public var playerItem: AVPlayerItem?
func playStream(url: URL) {
let asset = AVURLAsset(url: url)
playerItem = AVPlayerItem(asset: asset)
participant = AVPlayer(playerItem: playerItem)
participant?.play()
}
Stream Evaluation: When analyzing the video stream utilizing FFmpeg:
CopyInput #0, hls, from 'https://svs.itworkscdn.internet/smcwatarlive/smcwatar/chunks.m3u8':
Stream #0:0: Video: h264, yuv420p(television, bt709), 1920x1080 [SAR 1:1 DAR 16:9], 25 fps
Stream #0:1: Audio: aac, 44100 Hz, stereo, fltp
Tried Options:
Utilizing MobileFFmpeg:
let command = [
"-i", streamUrl,
"-vn",
"-acodec", "aac",
"-ac", "2",
"-ar", "44100",
"-b:a", "128k",
"-f", "mpegts",
"udp://127.0.0.1:12345"
].joined(separator: " ")
ffmpegProcess = MobileFFmpeg.execute(command)
I
ssue: Whereas FFmpeg efficiently extracts audio, playback by means of AVPlayer does not work reliably.
Tried utilizing HLS output:
let command = [
"-i", streamUrl,
"-vn",
"-acodec", "aac",
"-ac", "2",
"-ar", "44100",
"-b:a", "128k",
"-f", "hls",
"-hls_time", "2",
"-hls_list_size", "3",
outputUrl.path
]
Difficulty: Creates short-term information however faces synchronization points with reside streams.
Testing URLs:
Audio+Video: https://svs.itworkscdn.internet/smcwatarlive/smcwatar/chunks.m3u8
Audio Solely: https://mbcfm-radio.mbc.internet/mbcfm-radio.m3u8
Necessities:
- Actual-time audio extraction from HLS stream
- Keep reside streaming capabilities
- Full AirPlay help
- Minimal information utilization (keep away from downloading video content material)
- Deal with community interruptions gracefully
Questions:
- What’s essentially the most environment friendly method to extract solely audio from an HLS stream in real-time?
- Is there a method to inform AVPlayer to disregard video tracks utterly?
- Are there higher options to FFmpeg for this particular use case?
- What is the beneficial method for dealing with AirPlay with modified streams?
Any steering or various approaches could be vastly appreciated. Thanks!
What I Tried:
- Direct AVPlayer Implementation:
- Used normal AVPlayer to play HLS stream
- Anticipated it to permit choosing audio-only tracks
- Consequence: All the time downloads each video and audio, consuming pointless bandwidth
- FFmpeg Audio Extraction:
let command = [
"-i", "https://svs.itworkscdn.net/smcwatarlive/smcwatar/chunks.m3u8",
"-vn", // Remove video
"-acodec", "aac", // Audio codec
"-ac", "2", // 2 channels
"-ar", "44100", // Sample rate
"-b:a", "128k", // Bitrate
"-f", "mpegts", // Output format
"udp://127.0.0.1:12345" // Local stream
]
ffmpegProcess = MobileFFmpeg.execute(command)
Anticipated: Clear audio stream that AVPlayer may play
Consequence: FFmpeg extracts audio however AVPlayer cannot play the UDP stream
- HLS Segmented Method:
swiftCopylet command = [
"-i", streamUrl,
"-vn",
"-acodec", "aac",
"-f", "hls",
"-hls_time", "2",
"-hls_list_size", "3",
outputUrl.path
]
Anticipated: Create native HLS playlist with audio-only segments
Consequence: Creates information however faces sync points with reside stream
Anticipated Habits:
- Stream performs audio solely
- Minimal information utilization (no video obtain)
- Working AirPlay help
- Actual-time playback with out delays
Precise Outcomes:
- Both downloads full video stream (wasteful)
- Or fails to play extracted audio
- AirPlay points with modified streams
- Sync issues with reside content material