In my Xamarin Forms Android app I'm sending audio through the ear piece instead of the normal speaker. I'm doing something like:
myMediaPlayer.SetAudioAttributes(new AudioAttributes.Builder().SetLegacyStreamType(Stream.VoiceCall).Build());
The deprecated version of the above is
myMediaPlayer.SetAudioStreamType(Stream.VoiceCall);
Either way, this seems to work (though, if there is a better way, please let me know).
HOWEVER, I cannot control the volume. The sound correctly comes out of the ear speaker only, but it is at a constant volume, ignoring my volume key presses (though the volume meter displays on the screen going up and down as a press the buttons). ... (for clarification, I'm not trying to control the volume programatically, I simply want the device to adjust the volume as one would expect.)
Any help?
UPDATE
I've also tried this code:
myMediaPlayer.SetAudioAttributes(new AudioAttributes.Builder().SetContentType(AudioContentType.Music).SetUsage(AudioUsageKind.VoiceCommunication).Build());
I have two goals:
Play only out of the ear piece (or headphones if attached)
Be able to control the volume (which I thought would be a given)
UPDATE with Code Sample
The following will play through the earpiece, but not change volume.
public void Play(string url)
{
var myMediaPlayer = new MediaPlayer();
myMediaPlayer.SetDataSource(url);
if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop)
myMediaPlayer.SetAudioAttributes(new AudioAttributes.Builder().SetContentType(AudioContentType.Music).SetUsage(AudioUsageKind.VoiceCommunication).Build());
else
myMediaPlayer.SetAudioStreamType(Stream.VoiceCall);
myMediaPlayer.Prepare();
myMediaPlayer.Start();
}
Related
public float GetAxis()
{
if (inputDevice == InputDevice.MouseKeyboard)
{
return Input.GetAxis(this.buttonName);
}
}
This code is working perfectly on my Windows 7 x64 PC. My Project Input settings are ordinal:
Input settings:
But I watched some videos on youtube where people playing my game. And they can't use mouse in it. Looks like Input.GetAxis("Mouse X") and Input.GetAxis("Mouse Y") has not returning proper values for them and they can't control camera in game.
Other input is working fine for them.
My Unity version is 5.6.0f3 and I can't upgrade to actual version because game's code is too complex.
How to troubleshot and fix it? I have not build for other platforms then windows x86 and x64.
Input object was constructed:
public GenericInput rotateCameraXInput = new GenericInput("Mouse X", "RightAnalogHorizontal");
To read delta mouse movement I am running this method in LateUpdate():
protected virtual void CameraInput()
{
if (tpCamera == null || cc.lockCamera)
return;
var Y = rotateCameraYInput.GetAxis();
var X = rotateCameraXInput.GetAxis();
}
I've come across this issue myself while using an RDP session or some kind of remote viewer such as TeamViewer. Mouse X and Mouse Y read the output directly from a device. If the device is not directly plugged into the machine that the player is being ran on then the inputs will not be properly retrieved. I'm not sure if this is the case for you, but this is the only instance I can think of these not being picked up.
Maybe you should add a bit of code that gets the mouse position each frame and outputs the difference, this would bypass the Mouse X/Y inputs anyways.
Update. It is not a bug. I've just missed something in my project.
I have a script to control the speed of mouse-controlled camera and PlayerPrefs variable to change it. And, in some conditions, that variable was set to 0. But for my case, it has already been set to registry and on my PC everything was working fine.
Maybe I need to delete this question, because it has not provided enough data.
I found this thread at unity forum There are some people who encountered the same issue on real Windows PC with different Unity versions and different mouse drivers.
This is an old Unity hardware compatibility bug. Looks like it can't be fixed other then upgrading Unity or using other Input system.
I'm a total beginner in Unity and created a function that simply sets the text of a text element when a touch is detected like this:
// Update is called once per frame
void Update () {
if (didTap ()) {
print ("did tap!");
tapText.text = "TAP!";
}
}
private bool didTap() {
print ("checking didtap");
if (Input.touchCount > 0) {
Touch initialTouch = Input.GetTouch (0);
return initialTouch.phase == TouchPhase.Began;
}
return false;
}
When I run this on an actual device (Android phone) it works perfectly, but when I 'click' in the unity editor when running the game nothing happens. I'm running OSX 10.12.2. Anything I need to configure to have the mouse mimic touch events?
You can duplicate Unity's play mode window onto your mobile device by using the UnityRemote app. This will allow you to interact with your phone's features, while still running Unity on your computer.
UnityRemote requires some setup in Unity along with downloading the app. Consider watching this video: Unity Remote Setup Tutorial
Alternatively, see the answer from Hellium in this question, in conjunction with getting the mouse clicks, to only compile code based on the device used.
There's an odd difference between "touch" input and "mouse" input in Unity. Input.touchCount will always return 0 while you're running in the Editor but Input.GetMouseButtonDown(0) works for both the Editor and the first touch of one or more touches while on a mobile build.
You have two options to solve this issue via code (your other option is the remote ryemoss mentioned):
If you're only ever using one touch, use Input.GetMouseButtonDown(0) and Input.GetMouseButtonUp(0).
Use #if UNITY_IOS, #if UNITY_ANDROID and #if UNITY_EDITOR tags to write separate input readers for your platforms and then have them all call into the same functionality.
I have an WPF+SharpDX Windows application that displays to the OSVR HDK via a fullscreen window on the screen that is the HDK. This setup works well, but it requires users to state which screen the HDK is on.
I would like to have that automatically detected, but haven't seen anything in the API on which screen is the headset.
Currently I render in a window:
var bounds = dxgiDevice.Adapter.Outputs[_selectedOutput].Description.DesktopBounds;
form.DesktopBounds = new System.Drawing.Rectangle(
bounds.X, bounds.Y, bounds.Width, bounds.Height);
And _selectedOutputis the thing I'm looking for.
I don't support direct mode at this time and I'm using Managed-OSVR. The application will run on Windows 8/8.1/10.
It's been a while since I coded anything for OSVR, but here's from what I remember:
If you're running in extended mode, the OSVR is treated as a regular display. You can rearrange it as any other screen. The output location can be configured in the OSVR config file.
I used the following (Java) to retrieve the position and size to set up my window:
osvrContext.getRenderManagerConfig().getXPosition()
osvrContext.getRenderManagerConfig().getYPosition()
osvrContext.getDisplayParameters().getResolution(0).getWidth()
osvrContext.getDisplayParameters().getResolution(0).getHeight()
To clarify: I don't know if you can retrieve the id of the display in extended mode. From what I know, it's only defined as a position and size on the desktop.
I hope that it helps you, somewhat.
I'm writing a Mac app that plays MPEG-4 movies using AVPlayer.
My app supports both local movies and movies from the internet, via an “Open Location” dialog. In the latter case, when the user enters a URL and presses the OK button, my app opens the URL as a document.
Local files are easy—Launch Services will tell Finder, Dock, etc. not to light my app up for any local file that isn't a .mp4 or similar. If the user forces my app to open some random file (e.g., by holding down ⌘ when dragging it onto my app), that's their own fault.
Non-local (e.g., internet) URLs are the problem. If I supply a URL that doesn't lead to an MPEG-4, I need to show an alert and close the document.
Of course, I'm not downloading the URL myself; I just hand it to AVPlayer.
So I need a way to be notified by my AVPlayer that what I've given it is not a movie.
I've tried observing the player's status. That gets set to AVPlayerStatusReadyToPlay.
I've tried observing the player's currentItem's tracks. At least on Lion, for an invalid movie, the item's tracks never changes. (This stands to reason—the only reason it would change would be tracks coming in, which is, by definition, impossible for a non-movie.)
I can't just check tracks when status changes, because that may not be set yet (on Mavericks, status changes before tracks).
So, how can I be notified by my AVPlayer that it has conclusively determined that what the URL refers to is not anything it can play?
It's absolutely not definitive, but in my experience, when the player's status becomes AVPlayerStatusReadyToPlay, you can inspect the playable property of asset of the player's currentItem. If playable is YES, you can assume the URL led to a viable MP4. If not, you can assume it did not.
- (void) observeValueForKeyPath:(NSString*)keyPath
ofObject:(id)object
change:(NSDictionary*)change
context:(void*)context
{
if( [keyPath isEqualToString:#"status"] ) {
if( self.player.status == AVPlayerStatusReadyToPlay &&
self.player.currentItem.asset.playable ) {
[self.playerView.player play];
}
else {
// TODO: show an error dialog here.
[self.window close];
}
}
}
I've code similar to the above in one of my apps, and it seems to work as expected in every case I've tried. I can whip up a test app with it if you like.
When registering the MinimalMediaRouteProvider/MediaRouteButton from Androids Chromecast SDK, we get a standard dialog for connecting to existing Cromecast Devices. Once connected to the device, same dialog also provides a way to set the volume using a draggable seek bar. I am having trouble synchronizing the position of this volume seek bar with the actual volume that is already set in the Chromecast device.
As part of registering the MinimalMediaRouteProvider we provide a com.google.cast.MediaRouteAdapter implementation. The onSetVolume(volume) of this interface is called when the user drags the volume seekBar above. This gives us a god way to update the volume level of the connected chromecast channel by using messageStream.setVolume(volume).
The problem is that once we update the volume, there is no way to tell back the MinimalMediaRouteProvider UI that the volume has changed so it can position itself accordingly - currently it always shows the volume as 0.
What is the proper way to notify the MinimalMediaRouteProvider about the current volume level so it can update its volume UI?
Looking at the MediaRoute sample included with support library 7, there seem to be a way to create MediaRouteDescriptor, update the volume there and thus communicate this back to the MediaRouteProvider, but but it is not very clear how to do this in the content of Chromecast/MinimalMediaRouteProvider.
You can call MediaRouteStateListener.onVolumeChanged() to update the volume seekbar.
I have a more detailed answer here:
https://stackoverflow.com/a/18867128/1334870
To get volume immediately from VideoCastManager:
mVolume = (int) (mCastManager.getVolume() * 100) // cast volume is double
To receive system-based volume changes in the receiver (i.e. the on-screen volume slider pop-up, other connected devices changing the volume), you'll need to add a cast consumer in your controller activity:
private VideoCastConsumerImpl mCastConsumer = new VideoCastConsumerImpl() {
public void onVolumeChanged(double volume, boolean isMute)
{
mVolumeSeekBar.setProgress((int) (volume *100));
}
};
For more details:
Android Sender App Development (Aug '14)