我正在开发一个具有视频流功能的应用程序。我正在使用 firebase 数据库和 firebase 存储。我正在尝试查找有关 firebase 存储如何处理视频文件的一些文档,但实际上找不到太多。
文档中提到,firebase 存储与其他谷歌应用服务一起工作,以允许 CDN 和视频流,但所有搜索似乎都导致了死胡同。有什么建议吗?
我正在开发一个具有视频流功能的应用程序。我正在使用 firebase 数据库和 firebase 存储。我正在尝试查找有关 firebase 存储如何处理视频文件的一些文档,但实际上找不到太多。
文档中提到,firebase 存储与其他谷歌应用服务一起工作,以允许 CDN 和视频流,但所有搜索似乎都导致了死胡同。有什么建议吗?
我认为有几种类型的视频流,这可能会改变我们的答案:
在使用 Firebase 存储和 Firebase 实时数据库构建了一个直播 Periscope 风格的应用程序后,我强烈建议不要这样做——我们上传了三秒钟的块并通过实时数据库同步它们。虽然它有效(令人惊讶地好),但在非常好的互联网上存在约 5 秒的延迟,而且它也不是最有效的解决方案(毕竟,您正在上传和存储该视频,而且没有任何转码) . 我建议使用一些 WebRTC 风格,专为视频传输而构建,并使用实时数据库在流旁边发送信号。
另一方面,在 Firebase 功能上构建移动 YT 绝对是可能的。这里的诀窍是对视频进行转码(使用 Zencoder 或 Bitmovin 之类的东西,更多内容请参见:https ://cloud.google.com/solutions/media/ )将您上传的视频分割成不同分辨率的小块(以及不同的格式,例如,iOS 需要 HLS 进行流式传输)。您的客户端可以将块信息存储在实时数据库中(块名称、可用分辨率、块数量),并且可以随着视频的进行从存储中下载所述块。
如果您想从 Firebase 存储中传输视频,这是我发现的最佳方式。这将取决于您的视频文件的大小。我只请求 10-30mb 的文件,所以这个解决方案对我很有用。只需将 Firebase 网址视为常规网址:
String str = "fire_base_video_URL";
Uri uri = Uri.parse(str);
videoViewLandscape.setVideoURI(uri);
progressBarLandScape.setVisibility(View.VISIBLE);
videoViewLandscape.requestFocus();
videoViewLandscape.start();
如果要循环播放视频:
videoViewLandscape.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.setLooping(true);
}
});
如果您想在视频开始之前显示进度条,请执行以下操作:
videoViewLandscape.setOnInfoListener(new MediaPlayer.OnInfoListener() {
@Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
if (what == MediaPlayer.MEDIA_INFO_BUFFERING_END) {
progressBarLandScape.setVisibility(View.GONE);
return true;
}
else if(what == MediaPlayer.MEDIA_INFO_BUFFERING_START){
progressBarLandScape.setVisibility(View.VISIBLE);
return true;
}
return false;
}
});
这不是最好的做事方式,但它现在对我有用,直到我找到一个好的视频流服务。
所有其他问题都建议您使用 HLS 之类的协议。但是,仅当您为 Apple AppStore 开发的应用程序提供超过 10 分钟的视频时,才需要这样做。
在所有其他情况下,您只需将视频编码为 mp4 并将其上传到 firebase。然后,您的客户可以毫无问题地流式传输 mp4。只需确保您的 moov atom 位于 mp4 文件的开头即可。这允许立即开始播放视频,即使它没有完全加载。由于 Firebase 存储支持的可变位请求,用户还可以跳过或返回。
要对其进行测试,只需将视频上传到您的 Firebase 存储并在浏览器中打开即可。
您可以在 Firebase Cloud Storage 上托管 HLS 视频。它对我来说效果很好。诀窍是修改播放列表.m3u8
文件以包含存储文件夹前缀,以及?alt=media
播放列表中每个文件条目的后缀:
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:3
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:2.760000,
<folder_name>%2F1_fileSequence_0.ts?alt=media
#EXT-X-ENDLIST
您也不必真正使用服务器端转码,您可以让上传视频的客户端来做,并节省可观的成本。
我在这里用源代码编写了一个完整的教程:https ://itnext.io/how-to-make-a-serverless-flutter-video-sharing-app-with-firebase-storage-including-hls-and- 411e4fff68fa
这是我的确切实现,它在视图打开后立即从 Firebase 上的存储开始播放视频,然后让视图消失,然后添加一个按钮以单击后重播视频。
我有一个带有密钥的演示链接,因此您可以看到它有效。任何问题打我。
如果您想要在视频消失后的按钮,您只需要创建一个 IBAction。
// BackMuscles.swift
// Messenger
//
// Created by Zach Smith on 8/12/21.
// Copyright © 2021 spaceMuleFitness. All rights reserved.
//
import UIKit
import AVKit
import AVFoundation
class BackMuscles: UIViewController {
@IBOutlet weak var playv: UIButton!
let avPlayerViewController = AVPlayerViewController()
var avPlayer:AVPlayer?
override func viewDidLoad() {
super.viewDidLoad()
self.view.addBackground()
let movieUrl:NSURL? = NSURL(string: "https://firebasestorage.googleapis.com/v0/b/messenger-test-d225b.appspot.com/o/test%2FTestVideo.mov?alt=media&token=bd4ccba3-b446-43bc-809e-b1152aa3c2ff")
if let url = movieUrl {
self.avPlayer = AVPlayer(url: url as URL)
self.avPlayerViewController.player = self.avPlayer
}
NotificationCenter.default.addObserver(self, selector: #selector(playerDidFinishPlaying), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: avPlayerViewController.player?.currentItem)
self.present(self.avPlayerViewController, animated: true) { () -> Void in
self.avPlayerViewController.player?.play() // Do any additional setup after loading the view.
}
}
@objc func playerDidFinishPlaying(note: NSNotification) {
self.avPlayerViewController.dismiss(animated: true)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
@IBAction func playV(sender: UIButton) {
let amovieUrl:NSURL? = NSURL(string: "https://firebasestorage.googleapis.com/v0/b/messenger-test-d225b.appspot.com/o/test%2FTestVideo.mov?alt=media&token=bd4ccba3-b446-43bc-809e-b1152aa3c2ff")
if let aurl = amovieUrl {
self.avPlayer = AVPlayer(url: aurl as URL)
self.avPlayerViewController.player = self.avPlayer
self.present(self.avPlayerViewController, animated: true) { () -> Void in
self.avPlayerViewController.player?.play()
}
}
}
}
要使用 firestorage 播放视频,您只需要视频的完整 url。然后,您将此 url 传递到视频视图或 exoplayer。无需完整下载。videoview 将流式传输 YT 样式的内容
下面的视频非常好,它使用 exoplayer 进行流式传输,而不是 mediaplayer 或 videoViewLanscape https://www.youtube.com/watch?v=s_D5C5e2Uu0
try{
BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
TrackSelector trackSelector = new DefaultTrackSelector(new AdaptiveTrackSelection.Factory(bandwidthMeter));
simpleExoPlayer = ExoPlayerFactory.newSimpleInstance(this, trackSelector);
String vid = "https://www.youtube.com/watch?v=s_D5C5e2Uu0";
Uri uri= Uri.parse(vid);
DefaultHttpDataSourceFactory dataSourceFactory = new DefaultHttpDataSourceFactory("exoplayer_video");
ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
MediaSource mediaSource = new ExtractorMediaSource(uri,dataSourceFactory,
extractorsFactory, null, null);
videoView.setPlayer(simpleExoPlayer);
simpleExoPlayer.prepare(mediaSource);
simpleExoPlayer.setPlayWhenReady(true);
}
catch (Exception e){
}
以下是您需要的 buid gradle 应用程序文件中的实现。
implementation 'com.google.android.exoplayer:exoplayer:r2.4.0'
implementation 'com.google.android.exoplayer:exoplayer-core:r2.4.0'
implementation 'com.google.android.exoplayer:exoplayer-dash:r2.4.0'
implementation 'com.google.android.exoplayer:exoplayer-hls:r2.4.0'
implementation 'com.google.android.exoplayer:exoplayer-smoothstreaming:r2.4.0'
implementation 'com.google.android.exoplayer:exoplayer-ui:r2.4.0'