XCODE - (iOS) 计时/同步像幻灯片放映一样的视图到视频

发布于 2024-11-02 07:55:45 字数 11003 浏览 1 评论 0原文

这个问题已经困扰我几个月了——所以是时候放下我的骄傲并寻求一点帮助了。目前,这是在 UIWebView 作为 HTML5/JS 控制系统中完成的。但 UIWebview 坦率地说 sux 并希望将最后一个组件也本地化。

我有一个视频集合,在视频期间的特定时间点,我正在调用与视频中的时间段相关的说明页面。视频控件还充当说明页面的控制器。因此,无论到达什么时间点,相应的页面都会以动画方式就位。

我查看了很多很多选项,最接近的是 http 视频流并使用定时元数据来启动视图,但我将视频本地包含在设备上。而且,到目前为止还找不到任何看起来可行的东西。原则上看起来很简单,但如果我能找到一个像样的解决方案,我会被诅咒的......

有什么想法/指示吗?

这是在我剩下的头发脱落之前最后一次尝试本土化 - 我想我可能看到了我正在走向错误的方向,但如果你能抽出一点时间,我真的很感激!

目标是在包含一页说明的视频下方发出喊叫声。在 x 秒时,内容将刷新以对应于视频的该部分,并持续到下一次喊出新鲜内容为止。我已经成功地实现了这一目标。我一直(很多)摔倒的地方是,当我将视频擦回到上一部分时,shoutOut 内容仍保留在我擦洗的位置并永久保留在那里。或者如下面的代码所示,因为它被设置为定时可见持续时间,所以根本不会重新出现。

无论如何,这是代码...

标题:

// START:import
#import <UIKit/UIKit.h>
// START_HIGHLIGHT  
#import <MediaPlayer/MPMoviePlayerController.h>
#import "CommentView.h"
// END_HIGHLIGHT    


// START:def
// START:wiring
@interface MoviePlayerViewController : UIViewController {
    UIView *viewForMovie;
    // END:wiring
    // START_HIGHLIGHT  
    MPMoviePlayerController *player;
    // END_HIGHLIGHT
    // START:wiring
    UILabel *onScreenDisplayLabel;
    UIScrollView *myScrollView;
    NSMutableArray *keyframeTimes;
    NSArray *shoutOutTexts;
    NSArray *shoutOutTimes;
}

@property (nonatomic, retain) IBOutlet UIView *viewForMovie;
// END:wiring
// START_HIGHLIGHT
@property (nonatomic, retain) MPMoviePlayerController *player;
// END_HIGHLIGHT
@property (nonatomic, retain) IBOutlet UILabel *onScreenDisplayLabel;

@property (nonatomic, retain) IBOutlet UIScrollView *myScrollView;
@property (nonatomic, retain) NSMutableArray *keyframeTimes;


// START_HIGHLIGHT
-(NSURL *)movieURL;
- (void)timerAction:(NSTimer*)theTimer;
- (void) playerThumbnailImageRequestDidFinish:(NSNotification*)notification;
- (void)handleTapFrom:(UITapGestureRecognizer *)recognizer;
- (IBAction) getInfo:(id)sender;
- (void)removeView:(NSTimer*)theTimer;

// END_HIGHLIGHT
// START:wiring
@end
// END:def
// END:wiring
// END:import

主要:

@implementation MoviePlayerViewController
// START:synth
@synthesize player;
@synthesize viewForMovie;
@synthesize onScreenDisplayLabel;
@synthesize myScrollView;
@synthesize keyframeTimes;
// END:synth




// Implement loadView to create a view hierarchy programmatically, without using a nib.
// START:viewDidLoad
// START:viewDidLoad1
- (void)viewDidLoad {
    [super viewDidLoad];

    keyframeTimes = [[NSMutableArray alloc] init];

    shoutOutTexts = [[NSArray 
                      arrayWithObjects:@"This is a test\nLabel at 2 secs ", 
                      @"This is a test\nLabel at 325 secs",
                      nil] retain];
    shoutOutTimes = [[NSArray 
                      arrayWithObjects:[[NSNumber alloc] initWithInt: 2], 
                      [[NSNumber alloc] initWithInt: 325],
                      nil] retain];



    self.player = [[MPMoviePlayerController alloc] init];
    self.player.contentURL = [self movieURL];
    // END:viewDidLoad1


    self.player.view.frame = self.viewForMovie.bounds;
    self.player.view.autoresizingMask = 
    UIViewAutoresizingFlexibleWidth |
    UIViewAutoresizingFlexibleHeight;

    [self.viewForMovie addSubview:player.view];
    [self.player play];
    // START_HIGHLIGHT  

    [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(timerAction:) userInfo:nil repeats:YES];
    // END_HIGHLIGHT    

    // START:viewDidLoad1

    [self.view addSubview:self.myScrollView];


    [[NSNotificationCenter defaultCenter] 
     addObserver:self 
     selector:@selector(movieDurationAvailable:)
     name:MPMovieDurationAvailableNotification
     object:nil];
}
// END:viewDidLoad
// END:viewDidLoad1

// START:movieURL
-(NSURL *)movieURL
{
    NSBundle *bundle = [NSBundle mainBundle];
    NSString *moviePath = 
    [bundle 
     pathForResource:@"BigBuckBunny_640x360" 
     ofType:@"m4v"];
    if (moviePath) {
        return [NSURL fileURLWithPath:moviePath];
    } else {
        return nil;
    }
}
// END:movieURL

int position = 0;

- (void)timerAction:(NSTimer*)theTimer {
    NSLog(@"hi");
    int count = [shoutOutTimes count];
    NSLog(@"count is at %d", count);

    if (position < count) {
        NSNumber *timeObj = [shoutOutTimes objectAtIndex:position];
        int time = [timeObj intValue];
        NSLog(@"time is at %d", time);
        if (self.player.currentPlaybackTime >= time) {
            CommentView *cview = [[CommentView alloc] 
                                  initWithText:[shoutOutTexts objectAtIndex:position]];
            [self.player.view addSubview:cview];
            position++;
            [NSTimer scheduledTimerWithTimeInterval:4.0f target:self selector:@selector(removeView:) userInfo:cview repeats:NO];
        }
    }

}

- (void)removeView:(NSTimer*)theTimer {
    UIView *view = [theTimer userInfo];
    [view removeFromSuperview];
}
/*
 // Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
 - (void)viewDidLoad {
 [super viewDidLoad];
 }
 */

// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return YES;
}

- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}


- (void)dealloc {
    [super dealloc];
}

- (void) movieDurationAvailable:(NSNotification*)notification {
    MPMoviePlayerController *moviePlayer = [notification object];
    int duration = [moviePlayer duration];

    [[NSNotificationCenter defaultCenter] 
     addObserver:self 
     selector:@selector(playerThumbnailImageRequestDidFinish:)
     name:MPMoviePlayerThumbnailImageRequestDidFinishNotification
     object:nil];

    NSMutableArray *times = [[NSMutableArray alloc] init];
    for(int i = 0; i < 20; i++) {
        [times addObject:[NSNumber numberWithInt:5+i*((duration)/20)]];
    }
    [self.player requestThumbnailImagesAtTimes:times timeOption: MPMovieTimeOptionNearestKeyFrame];
}

int p = 0;
int ll=0;
- (void) playerThumbnailImageRequestDidFinish:(NSNotification*)notification {


    NSDictionary *userInfo;
    userInfo = [notification userInfo];

    NSNumber *timecode;
    timecode = [userInfo objectForKey: @"MPMoviePlayerThumbnailTimeKey"];


    [keyframeTimes addObject: timecode];

    UIImage *image;
    image = [userInfo objectForKey: @"MPMoviePlayerThumbnailImageKey"];

    int width = image.size.width;
    int height = image.size.height;
    float newwidth = 75 * ((float)width / (float)height);


    self.myScrollView.contentSize = CGSizeMake((newwidth + 2) * 20, 75);

    UIImageView *imgv = [[UIImageView alloc] initWithImage:image];
    [imgv setUserInteractionEnabled:YES];

    [imgv setFrame:CGRectMake(ll, 0, newwidth, 75.0f)];
    ll+=newwidth + 2;



    UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] 
                                             initWithTarget:self action:@selector(handleTapFrom:)];
    [tapRecognizer setNumberOfTapsRequired:1];

    [imgv addGestureRecognizer:tapRecognizer];
    [tapRecognizer release];


    [myScrollView addSubview:imgv];

}

- (void) getInfo:(id)sender
{
    MPMovieMediaTypeMask mask = self.player.movieMediaTypes;
    NSMutableString *mediaTypes = [[NSMutableString alloc] init];
    if (mask == MPMovieMediaTypeMaskNone) {
        [mediaTypes appendString:@"Unknown Media Type"];
    } else {
        if (mask & MPMovieMediaTypeMaskAudio) {
            [mediaTypes appendString:@"Audio"];
        }       
        if (mask & MPMovieMediaTypeMaskVideo) {
            [mediaTypes appendString:@"Video"];
        }

    }

    MPMovieSourceType type = self.player.movieSourceType;
    NSMutableString *sourceType = [[NSMutableString alloc] initWithString:@""];
    if (type == MPMovieSourceTypeUnknown) {
        [sourceType appendString:@"Source Unknown"];
    } else if (type == MPMovieSourceTypeFile) {
        [sourceType appendString:@"File"];
    } else if (type == MPMovieSourceTypeStreaming) {
        [sourceType appendString:@"Streaming"];
    }           


    CGSize size = self.player.naturalSize;

    onScreenDisplayLabel.text = [NSString stringWithFormat:@"[Type: %@] [Source: %@] [Time: %.1f of %.f secs] [Playback: %.0fx] [Size: %.0fx%.0f]", 
                                 mediaTypes,
                                 sourceType,
                                 self.player.currentPlaybackTime, 
                                 self.player.duration,
                                 self.player.currentPlaybackRate,
                                 size.width,
                                 size.height];
}

- (void)handleTapFrom:(UITapGestureRecognizer *)recognizer {
    NSArray *subviews = [myScrollView subviews];
    for (int i = 0; i < 20; i++) {
        if (recognizer.view == [subviews objectAtIndex:i]) {
            NSNumber *num = [keyframeTimes objectAtIndex:i];
            self.player.currentPlaybackTime = [num intValue];
            return;
        }
    }

}

@end

评论视图 标题:

#import <UIKit/UIKit.h>


@interface CommentView : UIView {

}

- (id)initWithFrame:(CGRect)frame andText:(NSString *) text;
- (id)initWithText:(NSString *) text;

@end

评论视图 主要:

#import "CommentView.h"


@implementation CommentView

- (id)initWithFrame:(CGRect)frame andText:(NSString *) text {
    if ((self = [super initWithFrame:frame])) {
        UIImage *image = [UIImage imageNamed:@"comment.png"];
        UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
        [self addSubview:imageView];

        CGRect rect = CGRectMake(20, 20, 200.0f, 90.0f);
        UILabel *label = [[UILabel alloc] initWithFrame:rect];
        label.text = text;
        label.numberOfLines = 3;
        label.adjustsFontSizeToFitWidth = YES;
        label.textAlignment = UITextAlignmentCenter;
        label.backgroundColor = [UIColor clearColor];
        [self addSubview:label];
    }
    return self;
}

- (id)initWithText:(NSString *) text {
    if ((self = [super init])) {
        UIImage *image = [UIImage imageNamed:@"comment.png"];
        UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
        [self addSubview:imageView];

        CGRect rect = CGRectMake(20, 20, 200.0f, 90.0f);
        UILabel *label = [[UILabel alloc] initWithFrame:rect];
        label.text = text;
        label.numberOfLines = 3;
        label.adjustsFontSizeToFitWidth = YES;
        label.textAlignment = UITextAlignmentCenter;
        label.backgroundColor = [UIColor clearColor];
        [self addSubview:label];
    }
    return self;
}



- (void)dealloc {
    [super dealloc];
}


@end

有人有什么想法吗?

干杯!

This one has been doing my head in for months - So time to swallow my pride and reach out for a little help. At the moment this is being done in UIWebView as HTML5/JS controlled system. But UIWebview frankly sux and looking to make this last component native too.

I have a collection of videos and at specific timed points during the video, I am calling a page of instructions that relate to the timed period in the video. The video controls also act as a controller for the instructions pages. So whatever timed point is reached, the corresponding page is animated into place.

I've looked in many, many options, with the closest coming in with http video streaming and using timed metadata to initiate a view, but I am containing the videos locally on the device. And, as yet cannot find anything that looks like it will work. Seems simple enough in principle, but I'll be damned if I can find a decent solution...

Any ideas / pointers?

Here's the last attempt at going native with this before the remainder of my hair fell out - I think I may be seeing where I was heading in the wrong direction, but if you can spare a few moments, I'd really appreciate it!

OBJECTIVE is to have a shoutOut that lives below the video that contains a page of instructions. At x seconds, the content will be refreshed to correspond to that portion of the video and persist until the next shoutOut for fresh content. This I have managed to achieve successfully. Where I have been falling down (a lot) is when I scrub the video back to a previous section, the shoutOut content remains at the position from which I scrubbed and remains there permanently. Or as the code is below, simply doesn't re-apear as it is set to a timed visible duration.

Anyway, here's the code...

Header:

// START:import
#import <UIKit/UIKit.h>
// START_HIGHLIGHT  
#import <MediaPlayer/MPMoviePlayerController.h>
#import "CommentView.h"
// END_HIGHLIGHT    


// START:def
// START:wiring
@interface MoviePlayerViewController : UIViewController {
    UIView *viewForMovie;
    // END:wiring
    // START_HIGHLIGHT  
    MPMoviePlayerController *player;
    // END_HIGHLIGHT
    // START:wiring
    UILabel *onScreenDisplayLabel;
    UIScrollView *myScrollView;
    NSMutableArray *keyframeTimes;
    NSArray *shoutOutTexts;
    NSArray *shoutOutTimes;
}

@property (nonatomic, retain) IBOutlet UIView *viewForMovie;
// END:wiring
// START_HIGHLIGHT
@property (nonatomic, retain) MPMoviePlayerController *player;
// END_HIGHLIGHT
@property (nonatomic, retain) IBOutlet UILabel *onScreenDisplayLabel;

@property (nonatomic, retain) IBOutlet UIScrollView *myScrollView;
@property (nonatomic, retain) NSMutableArray *keyframeTimes;


// START_HIGHLIGHT
-(NSURL *)movieURL;
- (void)timerAction:(NSTimer*)theTimer;
- (void) playerThumbnailImageRequestDidFinish:(NSNotification*)notification;
- (void)handleTapFrom:(UITapGestureRecognizer *)recognizer;
- (IBAction) getInfo:(id)sender;
- (void)removeView:(NSTimer*)theTimer;

// END_HIGHLIGHT
// START:wiring
@end
// END:def
// END:wiring
// END:import

Main:

@implementation MoviePlayerViewController
// START:synth
@synthesize player;
@synthesize viewForMovie;
@synthesize onScreenDisplayLabel;
@synthesize myScrollView;
@synthesize keyframeTimes;
// END:synth




// Implement loadView to create a view hierarchy programmatically, without using a nib.
// START:viewDidLoad
// START:viewDidLoad1
- (void)viewDidLoad {
    [super viewDidLoad];

    keyframeTimes = [[NSMutableArray alloc] init];

    shoutOutTexts = [[NSArray 
                      arrayWithObjects:@"This is a test\nLabel at 2 secs ", 
                      @"This is a test\nLabel at 325 secs",
                      nil] retain];
    shoutOutTimes = [[NSArray 
                      arrayWithObjects:[[NSNumber alloc] initWithInt: 2], 
                      [[NSNumber alloc] initWithInt: 325],
                      nil] retain];



    self.player = [[MPMoviePlayerController alloc] init];
    self.player.contentURL = [self movieURL];
    // END:viewDidLoad1


    self.player.view.frame = self.viewForMovie.bounds;
    self.player.view.autoresizingMask = 
    UIViewAutoresizingFlexibleWidth |
    UIViewAutoresizingFlexibleHeight;

    [self.viewForMovie addSubview:player.view];
    [self.player play];
    // START_HIGHLIGHT  

    [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(timerAction:) userInfo:nil repeats:YES];
    // END_HIGHLIGHT    

    // START:viewDidLoad1

    [self.view addSubview:self.myScrollView];


    [[NSNotificationCenter defaultCenter] 
     addObserver:self 
     selector:@selector(movieDurationAvailable:)
     name:MPMovieDurationAvailableNotification
     object:nil];
}
// END:viewDidLoad
// END:viewDidLoad1

// START:movieURL
-(NSURL *)movieURL
{
    NSBundle *bundle = [NSBundle mainBundle];
    NSString *moviePath = 
    [bundle 
     pathForResource:@"BigBuckBunny_640x360" 
     ofType:@"m4v"];
    if (moviePath) {
        return [NSURL fileURLWithPath:moviePath];
    } else {
        return nil;
    }
}
// END:movieURL

int position = 0;

- (void)timerAction:(NSTimer*)theTimer {
    NSLog(@"hi");
    int count = [shoutOutTimes count];
    NSLog(@"count is at %d", count);

    if (position < count) {
        NSNumber *timeObj = [shoutOutTimes objectAtIndex:position];
        int time = [timeObj intValue];
        NSLog(@"time is at %d", time);
        if (self.player.currentPlaybackTime >= time) {
            CommentView *cview = [[CommentView alloc] 
                                  initWithText:[shoutOutTexts objectAtIndex:position]];
            [self.player.view addSubview:cview];
            position++;
            [NSTimer scheduledTimerWithTimeInterval:4.0f target:self selector:@selector(removeView:) userInfo:cview repeats:NO];
        }
    }

}

- (void)removeView:(NSTimer*)theTimer {
    UIView *view = [theTimer userInfo];
    [view removeFromSuperview];
}
/*
 // Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
 - (void)viewDidLoad {
 [super viewDidLoad];
 }
 */

// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return YES;
}

- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}


- (void)dealloc {
    [super dealloc];
}

- (void) movieDurationAvailable:(NSNotification*)notification {
    MPMoviePlayerController *moviePlayer = [notification object];
    int duration = [moviePlayer duration];

    [[NSNotificationCenter defaultCenter] 
     addObserver:self 
     selector:@selector(playerThumbnailImageRequestDidFinish:)
     name:MPMoviePlayerThumbnailImageRequestDidFinishNotification
     object:nil];

    NSMutableArray *times = [[NSMutableArray alloc] init];
    for(int i = 0; i < 20; i++) {
        [times addObject:[NSNumber numberWithInt:5+i*((duration)/20)]];
    }
    [self.player requestThumbnailImagesAtTimes:times timeOption: MPMovieTimeOptionNearestKeyFrame];
}

int p = 0;
int ll=0;
- (void) playerThumbnailImageRequestDidFinish:(NSNotification*)notification {


    NSDictionary *userInfo;
    userInfo = [notification userInfo];

    NSNumber *timecode;
    timecode = [userInfo objectForKey: @"MPMoviePlayerThumbnailTimeKey"];


    [keyframeTimes addObject: timecode];

    UIImage *image;
    image = [userInfo objectForKey: @"MPMoviePlayerThumbnailImageKey"];

    int width = image.size.width;
    int height = image.size.height;
    float newwidth = 75 * ((float)width / (float)height);


    self.myScrollView.contentSize = CGSizeMake((newwidth + 2) * 20, 75);

    UIImageView *imgv = [[UIImageView alloc] initWithImage:image];
    [imgv setUserInteractionEnabled:YES];

    [imgv setFrame:CGRectMake(ll, 0, newwidth, 75.0f)];
    ll+=newwidth + 2;



    UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] 
                                             initWithTarget:self action:@selector(handleTapFrom:)];
    [tapRecognizer setNumberOfTapsRequired:1];

    [imgv addGestureRecognizer:tapRecognizer];
    [tapRecognizer release];


    [myScrollView addSubview:imgv];

}

- (void) getInfo:(id)sender
{
    MPMovieMediaTypeMask mask = self.player.movieMediaTypes;
    NSMutableString *mediaTypes = [[NSMutableString alloc] init];
    if (mask == MPMovieMediaTypeMaskNone) {
        [mediaTypes appendString:@"Unknown Media Type"];
    } else {
        if (mask & MPMovieMediaTypeMaskAudio) {
            [mediaTypes appendString:@"Audio"];
        }       
        if (mask & MPMovieMediaTypeMaskVideo) {
            [mediaTypes appendString:@"Video"];
        }

    }

    MPMovieSourceType type = self.player.movieSourceType;
    NSMutableString *sourceType = [[NSMutableString alloc] initWithString:@""];
    if (type == MPMovieSourceTypeUnknown) {
        [sourceType appendString:@"Source Unknown"];
    } else if (type == MPMovieSourceTypeFile) {
        [sourceType appendString:@"File"];
    } else if (type == MPMovieSourceTypeStreaming) {
        [sourceType appendString:@"Streaming"];
    }           


    CGSize size = self.player.naturalSize;

    onScreenDisplayLabel.text = [NSString stringWithFormat:@"[Type: %@] [Source: %@] [Time: %.1f of %.f secs] [Playback: %.0fx] [Size: %.0fx%.0f]", 
                                 mediaTypes,
                                 sourceType,
                                 self.player.currentPlaybackTime, 
                                 self.player.duration,
                                 self.player.currentPlaybackRate,
                                 size.width,
                                 size.height];
}

- (void)handleTapFrom:(UITapGestureRecognizer *)recognizer {
    NSArray *subviews = [myScrollView subviews];
    for (int i = 0; i < 20; i++) {
        if (recognizer.view == [subviews objectAtIndex:i]) {
            NSNumber *num = [keyframeTimes objectAtIndex:i];
            self.player.currentPlaybackTime = [num intValue];
            return;
        }
    }

}

@end

The Comment View Header:

#import <UIKit/UIKit.h>


@interface CommentView : UIView {

}

- (id)initWithFrame:(CGRect)frame andText:(NSString *) text;
- (id)initWithText:(NSString *) text;

@end

The Comment View Main:

#import "CommentView.h"


@implementation CommentView

- (id)initWithFrame:(CGRect)frame andText:(NSString *) text {
    if ((self = [super initWithFrame:frame])) {
        UIImage *image = [UIImage imageNamed:@"comment.png"];
        UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
        [self addSubview:imageView];

        CGRect rect = CGRectMake(20, 20, 200.0f, 90.0f);
        UILabel *label = [[UILabel alloc] initWithFrame:rect];
        label.text = text;
        label.numberOfLines = 3;
        label.adjustsFontSizeToFitWidth = YES;
        label.textAlignment = UITextAlignmentCenter;
        label.backgroundColor = [UIColor clearColor];
        [self addSubview:label];
    }
    return self;
}

- (id)initWithText:(NSString *) text {
    if ((self = [super init])) {
        UIImage *image = [UIImage imageNamed:@"comment.png"];
        UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
        [self addSubview:imageView];

        CGRect rect = CGRectMake(20, 20, 200.0f, 90.0f);
        UILabel *label = [[UILabel alloc] initWithFrame:rect];
        label.text = text;
        label.numberOfLines = 3;
        label.adjustsFontSizeToFitWidth = YES;
        label.textAlignment = UITextAlignmentCenter;
        label.backgroundColor = [UIColor clearColor];
        [self addSubview:label];
    }
    return self;
}



- (void)dealloc {
    [super dealloc];
}


@end

Thoughts anyone?

Cheers!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

羁拥 2024-11-09 07:55:45

定期监视 currentPlaybackTime 有什么问题(假设您使用的是实现 MPMediaPlayback 进行播放的实例)。

What's wrong with monitoring currentPlaybackTime at regular intervals (assuming you are using an instance that implements MPMediaPlayback for playback).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文