- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试制作一个应用程序来记录 UIImageView 的内容以及麦克风音频,并将它们实时记录到视频中。 (有点像会说话的汤姆猫应用程序)
我正在使用 AVAssetWriterInputPixelBufferAdaptor 毫无困难地记录 UIImageView 的内容,但我根本不知道如何将音频与此合并。这也不是因为缺乏尝试,我已经在这个特定问题上花了一个多星期的时间,梳理了这个网站、谷歌、iPhone 开发者论坛等。这不是我喜欢的。
与此最接近的引用是: How do I export UIImage array as a movie?
我可以分别捕获视频和音频,然后在事后将它们编码在一起(我真的很努力地解决这个问题),但是让这个应用程序实时录制非常理想。
这里是一些框架代码,演示了我迄今为止的记录:
这是 .h 文件
//
// RecordingTestProjectViewController.h
// RecordingTestProject
//
// Created by Sean Luck on 7/26/11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#import <CoreGraphics/CoreGraphics.h>
#import <CoreMedia/CoreMedia.h>
#import <CoreVideo/CoreVideo.h>
#import <QuartzCore/QuartzCore.h>
@interface RecordingTestProjectViewController : UIViewController
{
UIImageView *testView;
NSTimer *theTimer;
NSTimer *assetWriterTimer;
AVMutableComposition *mutableComposition;
AVAssetWriter *assetWriter;
AVAssetWriterInput *assetWriterInput;
AVAssetWriterInput *_audioWriterInput;
AVCaptureDeviceInput *audioInput;
AVCaptureSession *_capSession;
AVAssetWriterInputPixelBufferAdaptor *assetWriterPixelBufferAdaptor;
CFAbsoluteTime firstFrameWallClockTime;
int count;
}
-(void) writeSample: (NSTimer*) _timer;
-(void) startRecording;
-(void) pauseRecording;
-(void) stopRecording;
-(NSString*) pathToDocumentsDirectory;
@end
和 .m 文件
//
// RecordingTestProjectViewController.m
// RecordingTestProject
//
// Created by Sean Luck on 7/26/11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import "RecordingTestProjectViewController.h"
#import <AVFoundation/AVFoundation.h>
#import <CoreGraphics/CoreGraphics.h>
#import <CoreMedia/CoreMedia.h>
#import <CoreVideo/CoreVideo.h>
#import <QuartzCore/QuartzCore.h>
#define OUTPUT_FILE_NAME @"screen.mov"
#define TIME_SCALE 600
@implementation RecordingTestProjectViewController
- (void)dealloc
{
[super dealloc];
}
- (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.
}
#pragma mark - View lifecycle
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
testView = [[UIImageView alloc] initWithImage:nil];
testView.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
testView.userInteractionEnabled=NO;
testView.backgroundColor = [UIColor lightGrayColor];
[self.view addSubview:testView];
[testView release];
[super viewDidLoad];
[self startRecording];
}
-(void) writeSample: (NSTimer*) _timer
{
if ([assetWriterInput isReadyForMoreMediaData])
{
NSLog(@"count=%.i",count);
count=count+10;
UIGraphicsBeginImageContext(testView.frame.size);
[testView.image drawInRect:CGRectMake(0, 0, testView.frame.size.width, testView.frame.size.height)];
CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeNormal);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 0,1,1,1);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 5);
CGContextBeginPath(UIGraphicsGetCurrentContext());
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), 10+count/2, 10+count);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), 20+count*2, 20+count);
CGContextStrokePath(UIGraphicsGetCurrentContext());
testView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CVReturn cvErr = kCVReturnSuccess;
CGImageRef image = (CGImageRef) [testView.image CGImage];
// prepare the pixel buffer
CVPixelBufferRef pixelBuffer = NULL;
CFDataRef imageData= CGDataProviderCopyData(CGImageGetDataProvider(image));
cvErr = CVPixelBufferCreateWithBytes(kCFAllocatorDefault,testView.frame.size.width,testView.frame.size.height,kCVPixelFormatType_32BGRA,(void*)CFDataGetBytePtr(imageData),CGImageGetBytesPerRow(image),NULL,NULL,NULL,&pixelBuffer);
// calculate the time
CFAbsoluteTime thisFrameWallClockTime = CFAbsoluteTimeGetCurrent();
CFTimeInterval elapsedTime = thisFrameWallClockTime - firstFrameWallClockTime;
CMTime presentationTime = CMTimeMake (elapsedTime * TIME_SCALE, TIME_SCALE);
if (!cvErr)
{
// write the sample
BOOL appended = [assetWriterPixelBufferAdaptor appendPixelBuffer:pixelBuffer withPresentationTime:presentationTime];
if (appended)
{
}
else
{
NSLog (@"failed to append");
[self stopRecording];
}
}
CVPixelBufferRelease(pixelBuffer);
CFRelease(imageData);
}
if (count>1000)
{
[self stopRecording];
}
}
-(void) startRecording
{
// Doesn't record audio at all. Needs to be implemented.
// create the AVAssetWriter
NSString *moviePath = [[self pathToDocumentsDirectory] stringByAppendingPathComponent:OUTPUT_FILE_NAME];
if ([[NSFileManager defaultManager] fileExistsAtPath:moviePath])
{
[[NSFileManager defaultManager] removeItemAtPath:moviePath error:nil];
}
NSURL *movieURL = [NSURL fileURLWithPath:moviePath];
NSError *movieError = nil;
[assetWriter release];
assetWriter = [[AVAssetWriter alloc] initWithURL:movieURL fileType: AVFileTypeQuickTimeMovie error: &movieError];
NSDictionary *assetWriterInputSettings = [NSDictionary dictionaryWithObjectsAndKeys: AVVideoCodecH264, AVVideoCodecKey,[NSNumber numberWithInt:testView.frame.size.width], AVVideoWidthKey,[NSNumber numberWithInt:testView.frame.size.height], AVVideoHeightKey,nil];
[assetWriterInput release];
assetWriterInput =[AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:assetWriterInputSettings];
assetWriterInput.expectsMediaDataInRealTime = YES;
[assetWriter addInput:assetWriterInput];
[assetWriterPixelBufferAdaptor release];
assetWriterPixelBufferAdaptor = [[AVAssetWriterInputPixelBufferAdaptor alloc] initWithAssetWriterInput:assetWriterInput sourcePixelBufferAttributes:nil];
[assetWriter startWriting];
firstFrameWallClockTime = CFAbsoluteTimeGetCurrent();
[assetWriter startSessionAtSourceTime: CMTimeMake(0, TIME_SCALE)];
// start writing samples to it
[assetWriterTimer release];
assetWriterTimer = [NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:@selector (writeSample:) userInfo:nil repeats:YES];
[movieURL release];
[assetWriterInputSettings release];
}
-(void) stopRecording
{
if (assetWriterTimer!=nil)
{
[assetWriterTimer invalidate];
assetWriterTimer = nil;
[assetWriter finishWriting];
NSString *moviePath = [[self pathToDocumentsDirectory] stringByAppendingPathComponent:OUTPUT_FILE_NAME];
UISaveVideoAtPathToSavedPhotosAlbum (moviePath, nil, nil, nil);
}
}
-(void) pauseRecording
{
// needs to be implemented
}
-(NSString*) pathToDocumentsDirectory
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
return documentsDirectory;
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return YES;
}
@end
就是这样。如果任何人都可以修改此代码来录制麦克风音频,我相信除了我之外还有很多人会感激它。添加音频后,这将成为一个直接的框架,可以在应用程序屏幕转换中进行,以便开发人员演示他们的应用程序。
仅供引用:我的代码是开源的,很大程度上是根据 http://www.subfurther.com/blog/2011/04/12/voices-that-matter-iphone-spring-2011/ 的 VTMScreenRecorderTest 项目建模的。 。我进行了小幅度的修改并清理了内存泄漏。
最佳答案
我刚刚发现,如果您想将麦克风与录制的视频一起使用,则 CMTimestamp 必须同步。我尝试通过使用 CMSampleBufferSetOutputPresentationTimeStamp 更改音频上的采样时间来同步它们...但我遗漏了一些东西或者它不起作用。如果您捕获麦克风开始的时间并将其作为偏移量添加到视频中,则 StackOverflow 上的 AVAssetWriter 的每个示例似乎都能正常工作 -
以下是我为保持视频与麦克风同步所做的事情:
Img = Image
Snd = Sound
Avmedia = AVAssetWriter
etc.
#define Cmtm__Pref_Timescale_uk 10000
CMTime Duration_cmtm = CMTimeMakeWithSeconds( Avmedia_v->Img_Duration__Sec_df, Cmtm__Pref_Timescale_uk );
Avmedia_v->Img_cmtm = CMTimeAdd( Duration_cmtm, Avmedia_v->Exprt__Begin_cmtm );
if( [ Avmedia_v->Clrbuf__Adaptor_v appendPixelBuffer: Clrbuf_v withPresentationTime:
Avmedia_v->Img_cmtm ] is no )
{
//If the operation was unsuccessful,
//invoke the AVAssetWriter object’s finishWriting method in order to save a partially completed asset.
[ Avmedia_v->Avwriter_v finishWriting ];
CLog( Lv_Minor, "Movie Img exprt failed" );
}
关于iPhone - 使用 AVAssetWriterInputPixelBufferAdaptor 录制视频时从麦克风捕获音频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6838538/
我想开发一个虚拟麦克风驱动程序。请不要说任何关于 DirectShow 的事情——那不是“方式”。我需要一个适用于任何软件(包括 Skype 和 MSN)的解决方案。而 DirectShow 不符合这
我想使用媒体记录器从我的android应用程序记录音频。我已将音频源设置为麦克风,这使我可以从麦克风进行录制。但是我也很乐意检测是否连接了任何外部麦克风。如果是这样,那么它应该从中录制音频。 例如:如
在此先感谢您的帮助。 我正在开发一个用于研究目的的 Android 应用程序,需要禁用软输入键盘上的语音到文本按钮。这样做的原因是由于我正在开发的应用程序使用麦克风而出现的并发问题。我知道对于一般的应
目前,我正在启动主程序,该程序控制何时启动扬声器和麦克风线程。从那里,我还可以控制设备(USB耳机)上的静音/取消静音等。音频线程位于音频类的单独文件中。 此代码有效。现在,它以预设的特定循环计数捕获
OSX 10.10.3 ,也可以在10.8上重现 系统偏好设置中音频输入的当前状态是: 输入音量设置为0 当我对着麦克风讲话时,我看到条形音箱的没有动画 是否可以从AppleScript中的该状态恢复
我的问题:我目前有一个声音文件,其中包含我录制的特定声音。我希望能够识别该声音何时再次播放超过2秒钟。音量对我来说并不重要,我希望能够识别出何时播放该特定音符。例如,该文件保存了音符A(la)的录音,
这个标题可能看起来很荒谬,但我有问题。我有服务捕获线路,并将文件作为声音文件保存在系统上(该服务不是我开发的,我必须使用它)。 所以我想编写程序来选择声音文件(*.wav、*.mp3 等),然后该声音
我正在尝试编写一个java程序通过UDP发送实时麦克风数据,然后在VLC中接收数据。我基本上使用与 this post 中相同的代码将流打包并发送出去。当我在 VLC 中接收数据时,我什么也没得到。我
我有一个 IP 语音应用程序,我只想通过单击按钮将内置麦克风静音。我该怎么做? 最佳答案 您真的不需要将麦克风静音,对吗?只是停止处理传入的音频。这不是 SDK 需要为您做的事情,而是您需要做的事情。
软呢帽上的 qt5.7 检查了这个audio-to-chart example并发现 QIODevice::writeData 用于读取麦克风输入。由于它有效并且正在绘制来自麦克风的数据,因此该功能显
我想做的是: 在工具栏中添加一个按钮(麦克风图像)。 点击该按钮后,iOS 默认语音听写应该会被调用。 > 查询:我假设我们不能调用默认语音听写但想确认。他们是否有任何解决方法或任何方法来通过单击工具
我正在尝试编写一个 DirectShow 音频捕获过滤器,它可以被 Microsoft Lync 客户端识别为 Microphone 源。这些是我已经采取的步骤: 过滤器派生自CSource;它的输出
在我目前的工作中,我们正在开发一个使用 WebRTC 技术的应用程序。 我们想要测试我们的应用程序与 30 位用户的实时工作情况——一个包含视频、声音和麦克风的电话 session (一切都必须正常)
这可能是一个非常愚蠢的问题,因为我对 AudioKit 和一般的 IOS 音频真的很陌生。我想要实现的是从我的麦克风录制一个剪辑(或只是一个简单的文件记录)。 我不希望我的应用程序将输入(从麦克风)直
我正在尝试使用 AVAudioEngine 获取实时麦克风输入的 float 据。进行一次fft和fft之后的特殊算法。 当我编译代码时,我在控制台上变成了这个输出:0x000000000000000
我需要一种方法来通过 PulseAudio(通过 bash)获取麦克风的当前“响度”。我指的是麦克风拾取的声音音量。 我想复制一个音量计,就像您在 pavucontrol 中看到的那样。 最佳答案 在
如果另一个程序正在使用我计算机的摄像头/麦克风,我正在尝试检查 python (ubuntu)。 我想到了访问相机/麦克风时正在使用哪些系统调用。 我知道正在使用系统调用“access”和“open”
我正在做一个项目,我需要用户能够录制屏幕、音频和麦克风。目前我只能让它识别屏幕和音频。 首先,我捕获屏幕和其中的音频并将其保存到变量中。然后我正在捕获该变量以显示视频组件。 invokeGetDisp
根据官方documentation Android 10 (API level 29) and higher imposes a priority scheme that can switch the
我正在尝试开发一个应用程序来记录双方(麦克风和扬声器)的通话。我已经看到有一个应用程序 vrecorder 为 android 1.6 提供这个 vrecorder。 现在我想为 android 2.
我是一名优秀的程序员,十分优秀!