【问题标题】:iPhone SDK:How do you play video inside a view? Rather than fullscreeniPhone SDK:如何在视图内播放视频?而不是全屏
【发布时间】:2010-11-19 00:00:33
【问题描述】:

我正在尝试在 UIView 中播放视频,所以我的第一步是为该视图添加一个类并开始使用以下代码在其中播放电影:

- (IBAction)movie:(id)sender{
    NSBundle *bundle = [NSBundle mainBundle];
        NSString *moviePath = [bundle pathForResource:@"Movie" ofType:@"m4v"];
    NSURL *movieURL = [[NSURL fileURLWithPath:moviePath] retain];
    MPMoviePlayerController *theMovie = [[MPMoviePlayerController alloc] initWithContentURL:movieURL];
    theMovie.scalingMode = MPMovieScalingModeAspectFill;
    [theMovie play];
}

但这只会在应用程序自己的类中使用此方法时崩溃,但在其他地方很好。有谁知道如何在视图中播放视频?并避免它全屏显示?

【问题讨论】:

标签: ios objective-c media-player mpmovieplayer


【解决方案1】:

从 3.2 SDK 开始,您可以访问 MPMoviePlayerController 的视图属性,修改其框架并将其添加到您的视图层次结构中。

MPMoviePlayerController *player = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL fileURLWithPath:url]];
player.view.frame = CGRectMake(184, 200, 400, 300);
[self.view addSubview:player.view];
[player play];

这里有一个例子:http://www.devx.com/wireless/Article/44642/1954

【讨论】:

  • 不适用于 youtube 视频。在此处查看实现:iosdevelopertips.com/video/…
  • MPMoviePlayerController 是一个糟糕的库,如果您想要在视频中的当前时间进行特定控制。不完全是,并且有错误。最好的方法是AVPlayer,使用AVPlayerLayer。
  • MPMoviePlayerController 已弃用!
【解决方案2】:

最好的方法是使用嵌入视图的图层:

AVPlayer *player = [AVPlayer playerWithURL:[NSURL url...]]; // 

AVPlayerLayer *layer = [AVPlayerLayer layer];

[layer setPlayer:player];
[layer setFrame:CGRectMake(10, 10, 300, 200)];
[layer setBackgroundColor:[UIColor redColor].CGColor];
[layer setVideoGravity:AVLayerVideoGravityResizeAspectFill];

[self.view.layer addSublayer:layer];

[player play];

别忘了添加框架:

#import <QuartzCore/QuartzCore.h>
#import "AVFoundation/AVFoundation.h"

【讨论】:

  • 这里面的queuePlayer是什么?
  • 我已更改变量名。
  • 我已经这样做了,我得到的只是一个红色的盒子,里面有音频但没有视频:/
  • 这是由于 AVPlayerLayer 位于我认为的另一个视图或层的后面
  • 为什么使用层比使用视图更好?
【解决方案3】:

斯威夫特

这是一个独立的项目,因此您可以在上下文中查看所有内容。

布局

使用UIViewUIButton 创建如下布局。 UIView 将是我们将在其中播放视频的容器。

向项目添加视频

如果您需要一个示例视频来练习,您可以从sample-videos.com 获得一个。在此示例中,我使用的是 mp4 格式的视频。将视频文件拖放到您的项目中。我还必须将它显式添加到捆绑资源中(转到 Build Phases > Copy Bundle Resources,有关更多信息,请参阅this answer)。

代码

这是项目的完整代码。

import UIKit
import AVFoundation

class ViewController: UIViewController {

    var player: AVPlayer?

    @IBOutlet weak var videoViewContainer: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()
        initializeVideoPlayerWithVideo()
    }

    func initializeVideoPlayerWithVideo() {

        // get the path string for the video from assets
        let videoString:String? = Bundle.main.path(forResource: "SampleVideo_360x240_1mb", ofType: "mp4")
        guard let unwrappedVideoPath = videoString else {return}

        // convert the path string to a url
        let videoUrl = URL(fileURLWithPath: unwrappedVideoPath)

        // initialize the video player with the url
        self.player = AVPlayer(url: videoUrl)

        // create a video layer for the player
        let layer: AVPlayerLayer = AVPlayerLayer(player: player)

        // make the layer the same size as the container view
        layer.frame = videoViewContainer.bounds

        // make the video fill the layer as much as possible while keeping its aspect size
        layer.videoGravity = AVLayerVideoGravity.resizeAspectFill

        // add the layer to the container view
        videoViewContainer.layer.addSublayer(layer)
    }

    @IBAction func playVideoButtonTapped(_ sender: UIButton) {
        // play the video if the player is initialized
        player?.play()
    }
}

备注

  • 如果您要切换不同的视频,可以使用AVPlayerItem
  • 如果您只使用AVFoundationAVPlayer,那么您必须构建自己的所有控件。如果要全屏播放视频,可以使用AVPlayerViewController。为此,您需要导入 AVKit。它带有一整套用于暂停、快进、快退、停止等的控件。Herehere 是一些视频教程。
  • 您可能在其他答案中看到的MPMoviePlayerController 已弃用。

结果

项目现在应该是这样的。

【讨论】:

    【解决方案4】:

    查看您的代码,您需要设置电影播放器​​控制器视图的框架,并将电影播放器​​控制器的视图添加到您的视图中。另外,不要忘记将 MediaPlayer.framework 添加到您的目标中。

    这里有一些示例代码:

    #import <MediaPlayer/MediaPlayer.h>
    
    @interface ViewController () {
        MPMoviePlayerController *moviePlayerController;
    }
    
    @property (weak, nonatomic) IBOutlet UIView *movieView; // this should point to a view where the movie will play
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
    
        // Instantiate a movie player controller and add it to your view
        NSString *moviePath = [[NSBundle mainBundle] pathForResource:@"foo" ofType:@"mov"];
        NSURL *movieURL = [NSURL fileURLWithPath:moviePath];    
        moviePlayerController = [[MPMoviePlayerController alloc] initWithContentURL:movieURL];
        [moviePlayerController.view setFrame:self.movieView.bounds];  // player's frame must match parent's
        [self.movieView addSubview:moviePlayerController.view];
    
        // Configure the movie player controller
        moviePlayerController.controlStyle = MPMovieControlStyleNone;        
        [moviePlayerController prepareToPlay];
    }
    
    - (void)viewDidAppear:(BOOL)animated
    {
        [super viewDidAppear:animated];
    
        // Start the movie
        [moviePlayerController play];
    }
    
    @end
    

    【讨论】:

    • 我爱你!!非常感谢,我现在至少搜索了一个小时,而你只有一个简单有效的代码!
    • Xcode 6,iOS 8,这仍然有效。对我来说,关键是“准备玩”除了另一个答案。谢谢!
    • 还要注意 [moviePlayerController play];在 viewDidAppear 中...如果在 viewDidLoad 中,您可能只会在“movieView”中看到黑色背景,具体取决于您的 Xcode/iOS 版本。
    【解决方案5】:
    NSString * pathv = [[NSBundle mainBundle] pathForResource:@"vfile" ofType:@"mov"];
    playerv = [[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL fileURLWithPath:pathv]];
    
    [self presentMoviePlayerViewControllerAnimated:playerv];
    

    【讨论】:

      【解决方案6】:
      NSURL *url = [NSURL URLWithString:[exreciesDescription objectForKey:@"exercise_url"]];
      moviePlayer =[[MPMoviePlayerController alloc] initWithContentURL: url];
      [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(doneButtonClicked) name:MPMoviePlayerWillExitFullscreenNotification object:nil];
      [[moviePlayer view] setFrame: [self.view bounds]];  // frame must match parent view
      [self.view addSubview: [moviePlayer view]];
      [moviePlayer play];
      
      -(void)playMediaFinished:(NSNotification*)theNotification 
      {
          moviePlayer=[theNotification object];
          [[NSNotificationCenter defaultCenter] removeObserver:self
                                                          name:MPMoviePlayerPlaybackDidFinishNotification
                                                        object:moviePlayer];
      
      
          [moviePlayer.view removeFromSuperview];
      }
      
      -(void)doneButtonClicked
        {
               [moviePlayer stop];
              [moviePlayer.view removeFromSuperview];
               [self.navigationController popViewControllerAnimated:YES];//no need this if you are      opening the player in same screen;
        }
      

      【讨论】:

        【解决方案7】:

        Swift 版本:

        import AVFoundation
        
        func playVideo(url: URL) {
        
            let player = AVPlayer(url: url)
        
            let layer: AVPlayerLayer = AVPlayerLayer(player: player)
            layer.backgroundColor = UIColor.white.cgColor
            layer.frame = CGRect(x: 0, y: 0, width: 300, height: 300)
            layer.videoGravity = .resizeAspectFill
            self.view.layer.addSublayer(layer)
        
            player.play()
        }
        

        【讨论】:

        • 导入AVFoundationAVKit有什么区别?
        • 您不是每次用户播放视频时都添加另一个图层吗?
        • @Suragch 我不是 100% 确定,但我认为 AVKit 是建立在 AVFoundation 之上的,它是用于管理相机的较旧和较低级别的工具包。是的,这只是一个示例,因此它每次都会添加一个图层,但如果您要播放多个视频,只需编辑播放器而不是整个图层
        • 我查过了。如果您将AVPlayerViewController 与完整的视频播放控件一起使用,则需要AVKit。如果您正在构建自己的控件,则可以将AVFoundationAVPlayer 一起使用。
        【解决方案8】:

        使用以下方法。

        self.imageView_VedioContainer 是您的AVPlayer 的容器视图。

        - (void)playMedia:(UITapGestureRecognizer *)tapGesture
        {
            playerViewController = [[AVPlayerViewController alloc] init];
        
            playerViewController.player = [AVPlayer playerWithURL:[[NSBundle mainBundle]
                                                         URLForResource:@"VID"
                                                                 withExtension:@"3gp"]];
            [playerViewController.player play];
            playerViewController.showsPlaybackControls =YES;
            playerViewController.view.frame=self.imageView_VedioContainer.bounds;
            [playerViewController.view setAutoresizingMask:UIViewAutoresizingNone];// you can comment this line 
            [self.imageView_VedioContainer addSubview: playerViewController.view];
        }
        

        【讨论】:

          【解决方案9】:

          您无法在视图内播放视频。必须全屏播放。

          【讨论】:

          • 好吧,这很可惜,但我在应用商店看到其他应用的视频不是全屏播放,而是在主屏幕内以较小的视图播放,所以一定有办法。
          • 也许这些视频显示示例是带有额外声音轨道的连续图像。
          • 我认为这个答案已经过时了,就像在 SDK 3.2 中一样,应用程序中有明显的部分屏幕视频可以通过用户交互进入全屏。
          • 我同意!有人发现了,怎么办?
          • 我添加了另一个答案,概述了您在 3.2 中如何做到这一点
          猜你喜欢
          • 1970-01-01
          • 2012-08-14
          • 1970-01-01
          • 2013-07-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-12-07
          • 2012-05-23
          相关资源
          最近更新 更多