2013-07-01 44 views
7

Tôi có một số mã trực tuyến có thể quay video từ máy ảnh của iPhone và sau đó lưu nó vào một tập tin video và nó hoạt động tốt. Nhưng mục đích của tôi không phải là để lưu nó vào bộ nhớ, nhưng để gửi nó đến một máy chủ. Tôi đã phát hiện ra rằng có một máy chủ phương tiện miễn phí có tên WOWZA cho phép phát trực tuyến và cũng có tính năng Phát trực tiếp HTTP (HSL) của Apple và các máy chủ mong đợi video ở định dạng h.264 cho video và trong mp3 cho âm thanh. Bằng cách đọc một số tài liệu về Apple HSL, tôi cũng biết rằng nó cung cấp một url khác trong tệp danh sách phát cho từng phân đoạn của tệp phương tiện, sau đó được phát theo đúng thứ tự trên thiết bị thông qua trình duyệt. Tôi không chắc chắn làm thế nào để có được các phân đoạn nhỏ của tập tin được ghi lại bởi máy ảnh của điện thoại và cũng làm thế nào để chuyển đổi nó thành định dạng yêu cầu. Sau đây là đoạn code để chụp video:Cách gửi video được quay từ máy ảnh của iPhone đến máy chủ để phát trực tuyến?

Thực hiện tập tin

#import "THCaptureViewController.h" 
#import <AVFoundation/AVFoundation.h> 
#import "THPlayerViewController.h" 

#define VIDEO_FILE @"test.mov" 

@interface THCaptureViewController() 
@property (nonatomic, strong) AVCaptureSession *captureSession; 
@property (nonatomic, strong) AVCaptureMovieFileOutput *captureOutput; 
@property (nonatomic, weak) AVCaptureDeviceInput *activeVideoInput; 
@property (nonatomic, strong) AVCaptureVideoPreviewLayer *previewLayer; 
@end 

@implementation THCaptureViewController 

- (void)viewDidLoad 
{ 
[super viewDidLoad]; 

    #if TARGET_IPHONE_SIMULATOR 
    self.simulatorView.hidden = NO; 
     [self.view bringSubviewToFront:self.simulatorView]; 
    #else 
    self.simulatorView.hidden = YES; 
    [self.view sendSubviewToBack:self.simulatorView]; 
    #endif 

// Hide the toggle button if device has less than 2 cameras. Does 3GS support iOS 6? 
self.toggleCameraButton.hidden = [[AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo] count] < 2; 

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), 
    ^{ 
    [self setUpCaptureSession]; 
}); 
} 

#pragma mark - Configure Capture Session 

- (void)setUpCaptureSession 
{ 
self.captureSession = [[AVCaptureSession alloc] init]; 


NSError *error; 

// Set up hardware devices 
AVCaptureDevice *videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 
if (videoDevice) { 
    AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error]; 
    if (input) { 
     [self.captureSession addInput:input]; 
     self.activeVideoInput = input; 
    } 
} 
AVCaptureDevice *audioDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio]; 
if (audioDevice) { 
    AVCaptureDeviceInput *audioInput = [AVCaptureDeviceInput deviceInputWithDevice:audioDevice error:&error]; 
    if (audioInput) { 
     [self.captureSession addInput:audioInput]; 
    } 
} 

//Create a VideoDataOutput and add it to the session 
AVCaptureVideoDataOutput *output = [[AVCaptureVideoDataOutput alloc] init]; 
[self.captureSession addOutput:output]; 

// Setup the still image file output 
AVCaptureStillImageOutput *stillImageOutput = [[AVCaptureStillImageOutput alloc] init]; 
[stillImageOutput setOutputSettings:@{AVVideoCodecKey : AVVideoCodecJPEG}]; 

if ([self.captureSession canAddOutput:stillImageOutput]) { 
    [self.captureSession addOutput:stillImageOutput]; 
} 

// Start running session so preview is available 
[self.captureSession startRunning]; 

// Set up preview layer 
dispatch_async(dispatch_get_main_queue(), ^{ 
    self.previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.captureSession]; 
    self.previewLayer.frame = self.previewView.bounds; 
    self.previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; 

    [[self.previewLayer connection] setVideoOrientation:[self currentVideoOrientation]]; 
    [self.previewView.layer addSublayer:self.previewLayer]; 
}); 

} 

#pragma mark - Start Recording 

- (IBAction)startRecording:(id)sender { 

if ([sender isSelected]) { 
    [sender setSelected:NO]; 
    [self.captureOutput stopRecording]; 

} else { 
    [sender setSelected:YES]; 

    if (!self.captureOutput) { 
     self.captureOutput = [[AVCaptureMovieFileOutput alloc] init]; 
     [self.captureSession addOutput:self.captureOutput]; 
    } 

    // Delete the old movie file if it exists 
    //[[NSFileManager defaultManager] removeItemAtURL:[self outputURL] error:nil]; 

    [self.captureSession startRunning]; 

    AVCaptureConnection *videoConnection = [self connectionWithMediaType:AVMediaTypeVideo fromConnections:self.captureOutput.connections]; 

    if ([videoConnection isVideoOrientationSupported]) { 
     videoConnection.videoOrientation = [self currentVideoOrientation]; 
    } 

    if ([videoConnection isVideoStabilizationSupported]) { 
     videoConnection.enablesVideoStabilizationWhenAvailable = YES; 
    } 

    [self.captureOutput startRecordingToOutputFileURL:[self outputURL] recordingDelegate:self]; 
} 

// Disable the toggle button if recording 
self.toggleCameraButton.enabled = ![sender isSelected]; 
} 

- (AVCaptureConnection *)connectionWithMediaType:(NSString *)mediaType fromConnections:(NSArray *)connections { 
for (AVCaptureConnection *connection in connections) { 
    for (AVCaptureInputPort *port in [connection inputPorts]) { 
     if ([[port mediaType] isEqual:mediaType]) { 
      return connection; 
     } 
    } 
} 
return nil; 
} 

#pragma mark - AVCaptureFileOutputRecordingDelegate 

- (void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error { 
if (!error) { 
    [self presentRecording]; 
} else { 
    NSLog(@"Error: %@", [error localizedDescription]); 
} 
} 

#pragma mark - Show Last Recording 

- (void)presentRecording 
{ 
    NSString *tracksKey = @"tracks"; 
    AVAsset *asset = [AVURLAsset assetWithURL:[self outputURL]]; 
    [asset loadValuesAsynchronouslyForKeys:@[tracksKey] completionHandler:^{ 
    NSError *error; 
      AVKeyValueStatus status = [asset statusOfValueForKey:tracksKey error:&error]; 
      if (status == AVKeyValueStatusLoaded) { 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil]; 
          THPlayerViewController *controller = [mainStoryboard instantiateViewControllerWithIdentifier:@"THPlayerViewController"]; 
          controller.title = @"Capture Recording"; 
          controller.asset = asset; 
          [self presentViewController:controller animated:YES completion:nil]; 
        }); 
      } 
    }]; 
} 

#pragma mark - Recoding Destination URL 

- (NSURL *)outputURL 
{ 
    NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; 
    NSLog(@"documents Directory: %@", documentsDirectory); 
    NSString *filePath = [documentsDirectory stringByAppendingPathComponent:VIDEO_FILE]; 

    NSLog(@"output url: %@", filePath); 
    return [NSURL fileURLWithPath:filePath]; 
} 

@end 

tôi thấy link này trong đó cho thấy làm thế nào để chụp video trong khung. Nhưng tôi không chắc chắn rằng nếu quay video trong khung sẽ giúp tôi gửi video ở định dạng h.264 đến máy chủ. Điều này có thể được thực hiện, nếu có thì làm thế nào?

Here người đã đặt câu hỏi cho biết (trong nhận xét bên dưới câu hỏi) rằng anh ấy có thể thực hiện thành công, nhưng anh ấy chưa đề cập đến cách anh ấy quay video.

Vui lòng cho tôi biết loại dữ liệu nào sẽ được sử dụng để nhận các phân đoạn nhỏ của video được quay và cũng cách chuyển đổi dữ liệu đã chụp theo định dạng bắt buộc và gửi dữ liệu đến máy chủ.

+0

Vui lòng tham khảo url này sẽ hữu ích cho bạn. http://stackoverflow.com/questions/15518925/how-to-save-video-in-documents-folder-then-upload-to-server – saravanan

+0

tôi đoán ông là yêu cầu để phát trực tuyến không tiết kiệm video trong thư mục tài liệu và sau đó gửi đến máy chủ. – Leena

+0

Có. Tôi muốn phát trực tiếp video của mình. –

Trả lời

0

Bạn có thể sử dụng sdk trực tiếp. Bạn phải thiết lập máy chủ phát trực tuyến nginx. Hãy làm theo liên kết này. Tôi đã sử dụng nó và nó là giải pháp rất hiệu quả. https://github.com/ltebean/Live