我一直在尝试使用 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 文件的建议,我将不胜感激,谢谢!
“.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()
希望您现在可以播放......