Reference iOS TabController app...
Apple docs state that the AVAudioPlayer class does not provide support for streaming audio based on HTTP URL's. AVAudioPlayer plays only music embedded in the iApp with a file:// as a url.
Given that, I do use MPMoviePlayerViewController to play these web stored audio/mp3 files which it can handle.
This definitely works. I start out with a UIView with the lyrics for the song. At the very bottom of this UIView is a "Play" button. The user taps this button and the audio/mp3 plays; however, the audio/QuickTime (( Q )) graphic comes to the foreground and the lyrics disappear and will stay away until the user taps "Done". What I want to happen is that the audio/mp3 is played in the background, with the lyrics staying in front.
BTW, I really don't need for the "Done" button to be seen because the user can stop the audio by simply selecting another Tab.
Obviously this going to the background for the AV file makes sense because the MPMoviePlayerController object is designed to play video and the video ought to come to the front. It is consistent in that the audio also goes to the background .. except I need a way to defeat the audio/QuickTime (( Q )) graphic coming to the front.
I did insert code to determine if it was an audio file (mp3), versus a video file (mp4). So far so good ... and then if it was an audio file, within my actual playing segment, I have:
if ( NSClassFromString(#"MPMoviePlayerViewController") )
{
if (!isAudioFile)
{
[senderViewController
presentMoviePlayerViewControllerAnimated:moviePlayerViewController_];
}
}
[moviePlayerController_ play];
It actually works, that is, I actually hear the mp3 in the background, with the lyrics in front and the audio/QuickTime (( Q )) graphic does not show ...
BUT, what does happen is horrible, that is, the "Done" button shows over the lyrics I talked about with some sort of unknown ??? letters there.
The following answer is taken from an edit to the question:
if ( NSClassFromString(#"MPMoviePlayerViewController") )
{
if (!isAudioFile)
{
[senderViewController
presentMoviePlayerViewControllerAnimated:moviePlayerViewController_];
}
else
{
[moviePlayerController_ setControlStyle:MPMovieControlStyleNone];
}
}
FWIW, I really don't need a "Done" button because as soon as I go to another tab, either new music or a video, the music initially playing stops and the new AV file starts.
Related
I'm coding with posenet and p5js. I made a grid on my screen which plays different audio fragments on different x ranges. This works very well. However, if I keep it running and open another tab in my chrome webbrowser, the x position gets stuck in one area (it doesn't update anymore) and the same audio fragment is repeated until you get crazy.
Is there a way I can prevent this?
Well, some code would be great to be honest, but variables shouldn't really get stuck if you open another tab and so on, are you sure you haven't just missssspelled some variable, or some function or did one of those random mistakes?
If it truly is the p5.js I guess just try checking everytime draw fires if your canvas is still focused.
I believe you can also have canvas.hasFocus... exept you'd have to declare createCanvas as a variable (cause canvas is basically just a button or a textArea to html and javascript and p5)
Also I think there's a command to only allow for one audio channel and stuff in js and p5...
function draw() {
if(document.hasFocus()){
// all of your other code even
// background() and stuff...
}
}
How do you play another item when the one playing is finished (think playlist...)
I want to be able to create a new AVPlayerLayer and attach a player to it and start it in the background (ie. audio only).
Thanks
I know I can keep the audio of a streaming video in the background by doing self?.playerLayer?.player = nil when leaving the foreground. That is not what I am asking about.
You can skip a playerLayer if you like. AVPlayerLayer is only a visual class that uses an AVPlayer.
player = [AVPlayer playerWithURL:theURL];
[player play];
or
[yourPlayerLayer.player play]
Bob's your auntie
I'm working on a custom video player using the Media Foundation framework.
Currently, I can play, pause, stop or change the rate of the playback using an IMFMediaSession.
I can also retrieve a single frame using an IMFSourceReader.
I am currently able to render a frame (IMFSample) to a window area (a HWND) but only when the media session is stopped.
My goal is to be able to render a frame while the media session is paused.
(= doing frame-stepping using a source reader and not the media session)
I'm using GetDC, CreateBitmap, SelectObject and BitBlt to render my frame.
I tried using directd3d interfaces to fill it with a solid color (I'm really new to direct3d so followed a basic tutorial) but it didn't work.
Here is what I did : retrieving an IDirect3DDeviceManager9 with MR_VIDEO_ACCELERATION_SERVICE, doing OpenDeviceHandle, LockDevice, Clear, Begin/EndScene and Present.
None of these calls fail but I suspect the EVR is still painting the last frame.
So basically, I want the EVR to stop repainting its frame when I want and of course, I need to re-enable its painting process.
Any idea how to do that ?
Thanks
I finally got it working.
If you're interested, do the following:
retrieve IMFVideoDisplayControl and IMFVideoMixerBitmap from the media session using MFGetService
set up MFVideoAlphaBitmap structure and feed it to IMFVideoMixerBitmap::SetAlphaBitmap (there is a working example at the dedicated MSDN page)
call IMFVideoDisplayControl::RepaintVideo to update the output
To hide the previous content, don't set the alpha so that it's opaque.
Call IMFVideoMixerBitmap::ClearAlphaBitmap to get the previous content back.
And voilĂ !
I have the following code which works for Google Play Music, partly for Poweramp, not at all for stock music player
public void playSelectedPlaylist(String plid) {
Intent intent = new Intent( MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH);
intent.putExtra(MediaStore.Audio.Playlists.ENTRY_CONTENT_TYPE,
"android.intent.extra.playlist" );
intent.putExtra(MediaStore.EXTRA_MEDIA_FOCUS, "vnd.android.cursor.item/playlist");
intent.putExtra(SearchManager.QUERY, plid);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}else{
doToast("Sorry, no app was found to service this request", context);
}
}
The intent is INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH and it finds all those apps that have this in their manifest.xml file. So far so good. However, some of these are not really suitable for mp3 playlists such as Youtube.
Question 1:
How can I return just music players. (the MUSIC_PLAYER activity has been deprecated so I need to use seomething else)
Question 2:
when executing the above code Poweramp does present the user with the appropriate playlist. When clicking this and select "Play" nothing happens other than Poweramp asking me if I want to play filtered or play all. Selecting either has no effect.
Finally the question, why does Poweramp not play the playlist?
Additional:
the reason why the stock music player does not show is because it does not have the INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH. (I assume this will change in later versions)
Google Play Music has no problem and happily loads and starts to play the playlist
My Samsung has another music player which loads but seems unable to recognise it is a playlist I am passing and does not find anything although the playlist exists.
Anyone with suggestions, thoughts/suggestions I can try out?
Sorry if it looks like a noob question, but i'm new to titanium so some concepts are foreign to me.
I have a script called entry.js which is called from details.js using require('entry.js').
Now within entry.js i play a sound, depending on what entry is selected.
var player = Ti.Media.createSound({url:"/sounds/0"+e.id+".mp3"});
player.play();
That part is ok. The problem is when i go back to the details screen, and select another entry, the new sound overlaps the old one.
So i need a global value or object that i can pass down to entry.js to make sure if the sound is playing or not.
But if i declare a global TI.Media object in details.js i get an error in entry.js:
Cant find variable player
So the question is, how do i detect in a sub javascript file that an instance of audio is already running?
You can check whether the audio is playing using the isPlaying() method or try to stop the playing music when you get back to the details screen. You can use stop() method to stop the sound. It will stops playing the audio and resets the playback position to the beginning of the clip.
If you want to create a global variable or pass variable from one window to another, refer the following links
Passing parameters from currentWindow to the new window in Titanium
Passing variable between windows