AVPlayer 无法播放 .ts 视频流,但可以在 VLC 中运行

问题描述 投票:0回答:1

我一直在尝试使用 AVPlayer 在 SwiftUI 应用程序中播放 .ts(传输流)视频文件,但遇到了问题。 .ts 文件在 VLC 和其他媒体播放器中播放得很好,所以我很困惑为什么它在我的 iOS 应用程序中不起作用。

我创建了一个 SwiftUI 应用程序,并使用 AVPlayer 和 AVPlayerViewController 尝试从 .ts URL 流式传输视频。 当我在 VLC 中测试该 URL 时,该 URL 有效且有效,因此我知道该链接没有损坏。

struct ContentView: View {
    @State private var player: AVPlayer?
    let url = URL(string: "http://alibaba.gotoplucky.com:23000/live/Damianomaca/EfYpS6xSVy/260.ts")!
    let url3 = URL(string: "http://alibaba.gotoplucky.com:23000/live/Damianomaca/EfYpS6xSVy/26060.ts")!
    @State var isVPlayerOut = false
    var body: some View {
        
        Button {
            isVPlayerOut.toggle()
        } label: {
            Text("Open Video")
        }
        .sheet(isPresented: $isVPlayerOut) {
            VideoPlayerView(url: url3)
                
        }
        
    
    }
}

#Preview {
    ContentView()
}



struct VideoPlayerView: UIViewControllerRepresentable {
    let url: URL
    
    func makeUIViewController(context: Context) -> AVPlayerViewController {
        let playerViewController = AVPlayerViewController()
        let player = AVPlayer(url: url)
        print("\(url)")
        player.play()
        playerViewController.player = player
        return playerViewController
    }
    
    func updateUIViewController(_ uiViewController: AVPlayerViewController, context: Context) {
        // Optional updates
    }
}

如果有任何关于如何播放此 ts 文件的建议,我将不胜感激,谢谢!

ios swiftui video-streaming avfoundation avplayer
1个回答
0
投票

“.ts 文件在 VLC 和其他媒体播放器中播放得很好,
所以我很困惑为什么它在我的 iOS 应用程序中不起作用。”

AVPlayer
需要一个 M3U8 播放列表文件,其中列出了内部的
.ts
文件路径。

您可以尝试一些步骤...

(1)动态创建播放列表
通过使用字符串来包含播放列表的文本。

let my_string_m3u8 = """
#EXTM3U
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-TARGETDURATION:0
#EXT-X-VERSION:4
#EXT-X-MEDIA-SEQUENCE:0

#EXTINF:0.0,
http://alibaba.gotoplucky.com:23000/live/Damianomaca/EfYpS6xSVy/26060.ts

#EXT-X-ENDLIST
"""

(2) 以.M3U8扩展名保存文本

根据用 Swift 进行黑客攻击 您可以使用以下方法保存文本文件(M3U8 数据):

let tmpFileURL = getDocumentsDirectory().appendingPathComponent("my_test_stream.m3u8")

do 
{ try my_string_m3u8.write(to: tmpFileURL, atomically: true, encoding: String.Encoding.utf8) } 
catch 
{
    // failed to write file – 
    // is bad permissions, bad filename, missing permissions, 
    // or more likely it can't be converted to the encoding
}

如果仍然无法显示播放,还可以考虑将 M3U8 保存为二进制(而不是文本)。 来自此参考(答案)的替代版本

let tmpFileURL = URL(fileURLWithPath:NSTemporaryDirectory()).appendingPathComponent("my_test_stream").appendingPathExtension("m3u8")
let wasFileWritten = (try? data.write(to: tmpFileURL, options: [.atomic])) != nil

if !wasFileWritten{ print("File was NOT saved") }

结果: 应该是应用程序临时目录中名为

my_test_stream.m3u8
的文件。

(3) 尝试播放一些视频
哪里...

let url4 = URL(string: "path-to-your-temp-dir-m3u8-file")!

然后可以用作:

let player = AVPlayer(url: url4)
print("\(url4)")
player.play()

希望您现在可以播放......

© www.soinside.com 2019 - 2024. All rights reserved.