Xamarin - 如何设置/更改 VideoView 显示预览方向
Posted
技术标签:
【中文标题】Xamarin - 如何设置/更改 VideoView 显示预览方向【英文标题】:Xamarin - How to set/change VideoView display preview orientation 【发布时间】:2017-06-07 09:45:03 【问题描述】:我从https://developer.xamarin.com/recipes/android/media/video/record_video/ 复制了一个代码,这是关于制作视频流的说明,我正在尝试更改其中的某些部分。
我已经尝试使用 SetOrientationHint(90) 将输出方向更改为 90
但由于此代码不使用 Camera 类,而仅使用 MediaRecorder 类。我如何旋转显示预览,因为它给了我一个 +90 度和横向预览?
我已经在 xml 和代码中尝试过旋转,但是预览变成了全黑。
这是代码
[Activity(Label = "App2", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : Activity, ISurfaceHolderCallback
string path = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath + "/test.mp4";
MediaRecorder recorder;
protected override void OnCreate(Bundle bundle)
base.OnCreate(bundle);
//Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
var record = FindViewById<Button>(Resource.Id.Record);
var stop = FindViewById<Button>(Resource.Id.Stop);
var play = FindViewById<Button>(Resource.Id.Play);
var video = FindViewById<VideoView>(Resource.Id.SampleVideoView);
//video.Rotation = 90;
record.Click += delegate
if (recorder == null)
recorder = startRecording(video);
else
Toast.MakeText(this, "Now recording", 0).Show();
;
stop.Click += delegate
if (recorder != null)
stopRecording(recorder);
recorder = null;
else
Toast.MakeText(this, "No video recording", 0).Show();
;
play.Click += delegate
if (path != null)
playVideo(video);
else
Toast.MakeText(this, "No video available", 0).Show();
;
//recorder = startRecording(video);
protected override void OnDestroy()
base.OnDestroy();
if (recorder != null)
recorder.Release();
recorder.Dispose();
recorder = null;
private void playVideo(VideoView video)
var uri = Android.Net.Uri.Parse(path);
video.SetVideoURI(uri);
video.Start();
private static void stopRecording(MediaRecorder recorder)
if (recorder != null)
recorder.Stop();
recorder.Release();
private MediaRecorder startRecording(VideoView video)
MediaRecorder recorder;
video.StopPlayback();
//video.Holder.AddCallback(this);
//video.Holder.SetType(SurfaceType.PushBuffers);
recorder = new MediaRecorder();
recorder.SetVideoSource(VideoSource.Camera);
recorder.SetAudiosource(AudioSource.Mic);
recorder.SetOutputFormat(OutputFormat.Default);
recorder.SetVideoEncoder(VideoEncoder.Default);
recorder.SetAudioEncoder(AudioEncoder.Default);
recorder.SetOutputFile(path);
recorder.SetOrientationHint(90);
recorder.SetPreviewDisplay(video.Holder.Surface);
if (recorder!=null)
try
recorder.Prepare();
recorder.Start();
catch (Exception)
Toast.MakeText(this, "Exception!", 0).Show();
return recorder;
public void SurfaceChanged(ISurfaceHolder holder, [GeneratedEnum] Format format, int width, int height)
throw new NotImplementedException();
public void SurfaceCreated(ISurfaceHolder holder)
throw new NotImplementedException();
public void SurfaceDestroyed(ISurfaceHolder holder)
throw new NotImplementedException();
更新
@Elvis Xia 的回答很有帮助。 这是新代码
[Activity(Label = "App2", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : Activity, ISurfaceHolderCallback
string path = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath + "/test.mp4";
MediaRecorder recorder;
Android.Hardware.Camera mCamera; //Android.Hardware is used because it will have
//problem with Android.Graphics
protected override void OnCreate(Bundle bundle)
base.OnCreate(bundle);
//Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
var record = FindViewById<Button>(Resource.Id.Record);
var stop = FindViewById<Button>(Resource.Id.Stop);
var play = FindViewById<Button>(Resource.Id.Play);
var video = FindViewById<VideoView>(Resource.Id.SampleVideoView);
record.Click += delegate
if (recorder == null)
recorder = startRecording(video);
else
Toast.MakeText(this, "Now recording", 0).Show();
;
stop.Click += delegate
if (recorder != null)
stopRecording(recorder, mCamera);
recorder = null;
else
Toast.MakeText(this, "No video recording", 0).Show();
;
play.Click += delegate
if (path != null)
playVideo(video);
else
Toast.MakeText(this, "No video available", 0).Show();
;
//recorder = startRecording(video);
protected override void OnDestroy()
base.OnDestroy();
if (recorder != null)
recorder.Release();
recorder.Dispose();
recorder = null;
private void playVideo(VideoView video)
var uri = Android.Net.Uri.Parse(path);
video.SetVideoURI(uri);
video.Start();
private static void stopRecording(MediaRecorder recorder, Android.Hardware.Camera mCamera)
if (recorder != null)
recorder.Stop();
recorder.Release();
mCamera.StopPreview();
mCamera.Release();
private MediaRecorder startRecording(VideoView video)
MediaRecorder recorder;
video.StopPlayback();
//video.Holder.AddCallback(this);
//video.Holder.SetType(SurfaceType.PushBuffers);
recorder = new MediaRecorder();
mCamera = GetCameraInstance();
mCamera.SetDisplayOrientation(90);
mCamera.Unlock();
recorder.SetCamera(mCamera);
recorder.SetVideoSource(VideoSource.Camera);
recorder.SetAudioSource(AudioSource.Mic);
recorder.SetOutputFormat(OutputFormat.Default);
recorder.SetVideoEncoder(VideoEncoder.Default);
recorder.SetAudioEncoder(AudioEncoder.Default);
recorder.SetOutputFile(path);
recorder.SetOrientationHint(90);
recorder.SetPreviewDisplay(video.Holder.Surface);
if (recorder!=null)
try
recorder.Prepare();
recorder.Start();
catch (Exception)
Toast.MakeText(this, "Exception!", 0).Show();
return recorder;
public void SurfaceChanged(ISurfaceHolder holder, [GeneratedEnum] Format format, int width, int height)
throw new NotImplementedException();
public void SurfaceCreated(ISurfaceHolder holder)
throw new NotImplementedException();
public void SurfaceDestroyed(ISurfaceHolder holder)
throw new NotImplementedException();
public static Android.Hardware.Camera GetCameraInstance()
Android.Hardware.Camera c = null;
try
c = Android.Hardware.Camera.Open();
catch (Exception e)
return c;
【问题讨论】:
【参考方案1】:但由于此代码不使用 Camera 类,而仅使用 MediaRecorder 类。我如何旋转显示预览,因为它给了我一个 +90 度和横向预览?
设置旋转度数后需要将Camera
与MediaRecorder
关联:
通过GetCameraInstace
获取相机实例:
public static Camera GetCameraInstance()
Camera c = null;
try
c = Camera.Open();
catch (Exception e)
return c;
在MainActivity.cs
记录按钮点击事件中,将camera
与MediaRecorder
关联,并在mCamera.Unlock
之前设置方向:
Camera mCamera
...
recorder = new MediaRecorder();
mCamera = ClassName.GetCameraInstance(); //ClassName if in different class.
//else just GetCameraInstance();
mCamera.SetDisplayOrientation(90);
mCamera.Unlock();
recorder.SetCamera(mCamera);
recorder.SetVideoSource(VideoSource.Camera);
【讨论】:
那台相机是来自 Android.Hardware 类的吗? . Utility.GetCameraInstance() 中的实用程序是什么?这是你的班级名字吗? 是的。Camera
来自 Android.Hardware
。 Utility
只是我用来封装GetCameraInstance
静态方法的一个类。
我已经尝试过了,它解决了我的定位问题 :) 感谢您的帮助。对于其他人:也不要忘记停止预览并释放相机。以上是关于Xamarin - 如何设置/更改 VideoView 显示预览方向的主要内容,如果未能解决你的问题,请参考以下文章
如何更改 Xamarin.Forms UWP 应用程序的强调色?
如何检测 xamarin UWP 应用程序中标签元素的文本值更改?