Firebase 存储视频流

Posted

技术标签:

【中文标题】Firebase 存储视频流【英文标题】:Firebase Storage Video Streaming 【发布时间】:2016-10-18 08:12:46 【问题描述】:

我正在开发一款具有视频流功能的应用。我正在使用 firebase 数据库和 firebase 存储。我正在尝试查找有关 firebase 存储如何处理视频文件的一些文档,但实际上找不到太多。

文档中提到,firebase 存储可与其他谷歌应用服务一起使用,以允许 CDN 和视频流,但所有搜索似乎都会导致死胡同。有什么建议吗?

【问题讨论】:

据我所知,Firebase 存储和 CDN 或视频流服务之间没有预制集成。您能否提供一个指向您看到此内容的文档的链接? "Firebase Storage 将您的文件存储在与默认 Google App Engine 应用共享的 Google Cloud Storage 存储桶中,让您可以通过 Firebase 和 Google Cloud API 访问它们。这使您可以灵活地上传和下载文件通过 Firebase 从移动客户端获取,并使用 Google Cloud Platform 进行图像过滤或视频转码等服务器端处理。” firebase.google.com/docs/storage/#key_functions 我也在尝试快速使用 Firebase 存储,但设置域失败。我认为 Firebase 托管可以快速使用,因为 Firebase 托管有自己的 CDN,我认为 Firebase 托管没有必要。 @gcas 你找到解决方案了吗? 【参考方案1】:

我认为有几种类型的视频流,这可能会改变我们的答案:

直播(订阅者在事件发生时观看) Youtube 风格(发布视频,最终用户在方便时观看)

使用 Firebase 存储和 Firebase 实时数据库构建了一个直播 Periscope 风格的应用程序,我强烈建议不要这样做——我们上传了三秒的块并通过实时数据库同步它们。虽然它有效(令人惊讶地好),但在非常好的互联网上存在约 5 秒的延迟,而且它也不是最有效的解决方案(毕竟,您正在上传和存储该视频,而且没有任何转码) .我建议使用一些 WebRTC 风格,专为视频传输而构建,并使用实时数据库在流旁边发送信号。

另一方面,在 Firebase 功能上构建移动 YT 绝对是可能的。这里的诀窍是对视频进行转码(使用 Zencoder 或 Bitmovin 之类的东西,更多:https://cloud.google.com/solutions/media/)将上传的视频分成不同分辨率的小块(和不同的格式,例如,ios 需要 HLS 进行流式传输) )。您的客户端可以在实时数据库中存储块信息(块名称、可用分辨率、块数量),并且可以随着视频的进行从存储中下载所述块。

【讨论】:

感谢您的提示和分享您的经验。我的应用程序的要求与选项 2 更相似。用户将能够上传其他用户稍后能够流式传输的短视频剪辑。实际上,我确实阅读了您前几天发给我的文章,但希望这两个服务之间可能会有一些更紧密的集成,而这两个服务没有记录在案。听起来像这些任务的 Firebase 存储和 GCP 定价,我可能会更好地寻找另一种视频托管服务。我目前正在研究 Sprout Video 和 Vimeo Pro。 我也会查看ziggeo.com,它们非常易于使用,并且可能拥有您在该领域取得成功所需的所有东西。 @gcas 你到底用了什么?我也在使用firebase的同一条船上。您是否使用其他服务(即 zencoder)使用 Firebase 存储和转码。 我也对你提到的 Vimeo Pro 感到困惑,Vimeo 水印不会通过 iframe 显示吗? @MikeMcDonald ,您能否详细描述一下如何进行 YT 风格的流式传输,尤其是如何逐块进行流式传输,而不是从 Firebase 存储中下载整个视频。此外,WebRTC 是否必须用于一对多视频流,即:广播?【参考方案2】:

如果您想从 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;
    
);

这不是最好的做事方式,但它现在对我有用,直到我找到一个好的视频流服务。

【讨论】:

这不是使用任何分块吗?它几乎看起来只是将视频源指向文件 URL。那正确吗?这行得通吗 性能可能很糟糕,除非在 Wifi 上:p PS 抱歉花了 1.5 年回复@SeanMC【参考方案3】:

2020:是的,firebase 存储视频流式传输既简单又可行。

所有其他问题都建议您使用 HLS 之类的协议。但是,只有在您为 Apple AppStore 开发的应用程序提供超过 10 分钟的视频时,才需要这样做。

在所有其他情况下,您只需将视频编码为 mp4 并将其上传到 firebase。然后,您的客户可以毫无问题地流式传输 mp4。只需确保您的 moov atom 位于 mp4 文件的开头即可。这允许立即开始播放视频,即使它没有完全加载。 借助 Firebase 存储支持的可变位请求,用户还可以跳过或返回。

要对其进行测试,只需将视频上传到您的 Firebase 存储并在浏览器中打开即可。

【讨论】:

我只是想知道视频大小是否为 1.4GB。如果一个人看这个,那么也在下载中,1.4GB 也是同时计算的??? (定价) 公平点,但如果没有 HLS(或 DASH),您仍然会浪费消费者的带宽,因为您不会使用自适应分辨率流;并非所有设备都想要或需要 1080p 流。 @Davie 是的,是的。此外,您的成本可能会从 HLS 或 DASH 中受益,因为您也必须为该带宽付费。 @Skyy2010 你是什么意思“只要确保你的 moov atom 在你的 mp4 文件的开头” @LaxmikantDange moov 原子是视频文件中的内容,它告诉视频的长度。如果它位于文件的开头,则您的媒体播放器可以立即开始播放。据我所知,这通常是这种情况。在我的用例中,我不需要做任何事情。但我相信谷歌可以帮助你了解更多细节。【参考方案4】:

您可以在 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

【讨论】:

嗨,您知道当我们有一个 200MB 的 HLS 视频以 10MB 为块并且用户只观看/缓冲了一半的视频时,Firebase 定价会发生什么?他们向我们收取总 MB 成本的一半吗?其次,说到 Flutter,HLS 是我们在 iOS 和 android 上都需要的,对吧?不需要 DASH 我们如何管理这些视频文件和 m3u8 文件块的安全性?假设我不希望某些用户访问某些视频文件。可能吗?最后,我们必须使用 Firebase 云存储吗?我们可以改用 Firebase 存储吗? 关于定价,您可能是对的,您只需为从 firebase 获取的内容付费,而使用 HLS,您只需获取接下来的几个块。 正如我在博文中提到的,两个平台都原生支持 HLS,但只有 Android 原生支持 DASH 为了安全(在博文中也提到),您必须在播放 m3u8 文件之前将 firebase 令牌添加到文件名中。我还没有测试过,但它应该可以工作。【参考方案5】:

这是我的确切实现,它在视图打开后立即从 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()

       
    

    


【讨论】:

【参考方案6】:

要使用 firestorage 播放视频,您只需要视频的完整网址即可。然后,您将此 url 传递到视频视图或 exoplayer。无需完整下载。 videoview 将流式传输 YT 样式的内容

【讨论】:

【参考方案7】:

如果你想创建一个类似YT的应用程序,你可以先压缩视频,我推荐使用这个library来管理视频压缩,我推荐这个link中的那个。我设法在 42 秒内将 118 毫克的视频压缩到 6 毫克。它还有一个很棒的演示应用程序,只需按照示例进行即可。

获得压缩文件后,将文件上传到存储,在您的客户端应用程序中,您将使用 Exo Player 等播放器播放视频 url。

【讨论】:

【参考方案8】:

下面的视频很不错,它使用 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'

【讨论】:

以上是关于Firebase 存储视频流的主要内容,如果未能解决你的问题,请参考以下文章

使用 Flutter Web 和 Firebase 存储播放视频

Android - 将视频/音频文件上传到 Firebase 存储

将视频上传到 Firebase 存储(未知错误)

Flutter-Firebase 存储上传视频

android-将视频压缩到firebase存储

如何在上传到 Firebase 存储之前压缩 Expo 中的视频?