i have created a UWP App which uses HTML5 Webradio streams.
Everything works fine but now i wanted to add track and artist information to the MediaPlayer Element.
This information will be shown if the user locked his device, on the start screen.
The first track if the user selects a stream is shown correctly. But I can't update this information without restart the Stream.
MediaItemDisplayProperties mdp = _mediaPlaybackItem.GetDisplayProperties();
mdp.Type = Windows.Media.MediaPlaybackType.Music;
mdp.MusicProperties.Artist = "TBA Artist";
mdp.MusicProperties.Title = "TBA Title";
mdp.Thumbnail = Windows.Storage.Streams.RandomAccessStreamReference.CreateFromUri(MainPage.Current.CurrentStream.PreviewImageUri);
_mediaPlaybackItem.ApplyDisplayProperties(mdp);
_mediaPlayer.Source = mpItem;
_mediaPlayer.Play();
If i take this lines into my refresh Method for Artist/Title, I also have to set the Source of _mediaPlayer again which will result to a pause of playing the music.
Does anyone have an idea how to fix this problem? Or give any advice I can look further.
Thanks Chris
If you want to update the Artist/Title, you should be able to use SystemMediaTransportControlsDisplayUpdater class, it provides functionality to update the music information that is displayed on the SystemMediaTransportControls.
We can set Artist/Title to the SystemMediaTransportControlsDisplayUpdater.MusicProperties property. Then we can use SystemMediaTransportControlsDisplayUpdater.Update method to update the metadata for the currently playing media.
Use the SystemMediaTransportControlsDisplayUpdater class to update the media info that is displayed by the transport controls, such as the song title or the album art for the currently playing media item. Get an instance of this class with the SystemMediaTransportControls.DisplayUpdater property. If your scenario requires it, you can update the metadata displayed by the system media transport controls manually by setting the values of the MusicProperties, ImageProperties, or VideoProperties objects exposed by the DisplayUpdater class.
For example:
SystemMediaTransportControlsDisplayUpdater updater = _systemMediaTransportControls.DisplayUpdater;
updater.MusicProperties.Artist = "artist";
updater.MusicProperties.AlbumArtist = "album artist";
updater.MusicProperties.Title = "song title";
updater.Thumbnail = RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Music/music1_AlbumArt.jpg"));
updater.Update();
Related
I'm using AVPlayer and AVPlayerItem in Swift to play internet radio streams.
Observing the "timedMetadata" gives me the track currently playing, however I never seem to get a handle of the radio title
See this example using VLC, I can obtain the "Now playing" part easily with timedMetadata, however I never receive the overall title of the radio "Title".
What am I missing, should I be observing something else to access the stream's/shoutcast/icecast information?
Try this:
let title = AVMetadataItem.metadataItems(from: urlAsset.commonMetadata, withKey: AVMetadataKey.commonKeyTitle, keySpace: AVMetadataKeySpace.common).first?.value as? String
print(title)
This works for media I have with metadata in the title (set using the Apple Music app). If this doesn't work for your media, please post it somewhere online along with your current code.
I'm currently trying to use UIVideoEditorViewController to trim a video file previously selected from the Photos app by using UIImagePickerController. I verified that after choosing the file and before creating UIVideoEditorViewController the file has the original resolution. However, after trimming the video, the output is always in 360p resolution despite setting the videoQuality property to high. All the applicable settings seem to be ignored for this property and the video ends up being compressed unnecessarily.
I have found multiple people reporting similar issues but yet have to find a workaround for this.
let editor = UIVideoEditorController()
editor.delegate = self
editor.videoMaximumDuration = 0 // No limit for now
// TODO: This should really work, however while testing it seems like the imported videos are always scaled down
// to 320p which equivalents the default value of .low.
editor.videoQuality = .typeHigh
editor.videoPath = internalURL.path
Any help would be greatly appreciated.
I have a question.
Recently I needed to add custom tags for recorded video. Local video on device not a streamed video. The task is to add some event specific tags in video, position of which could be set by pressing forward/backward like buttons like in any player.
It is not important whether the movie file will be mov file or mp4 format.
I searched on forum, found several samples how to add metadata using AVExportSession & it worked.
Although, when I tried to add metadata using AVAssetWriter. I wasn't able to append attributes to video.
What I do not understand is that after adding attribute, returned (time & duration) properties are always invalid.
For instance let's say I have a video with duration 2 seconds.
I have tried different key spaces. I am not able to write keys' from ID3 space.
IS ID3 used for stream video? (as far as I understood ID3 metadata of .mp3). Therefore, I was not able to write it into MPEG-4 file
I also used QuickTimeUserData & ISOUserData but again results are the same.
Here is an example
AVMutableMetadataItem *item2 = [AVMutableMetadataItem new];
item2.keySpace = AVMetadataKeySpaceiTunes;
item2.key = AVMetadataiTunesMetadataKeyUserComment;
item2.value = #"One two three";
item2.duration =CMTimeMakeWithSeconds(1, 1);
item2.time = CMTimeMakeWithSeconds(0, 1);
After reading I got the following:
AVMutableMetadataItem: 0xa4301f0, keySpace=itsk, key=\U00a9cmt, commonKey=(null), locale= (null), value=One two three, time={INVALID}, duration={INVALID}, extras={\n dataType = 1;\n}
I would like to use time & duration properties for metadata instead of writing custom data and processing it after that.
Ideally it would be great to append array of items with time = t1, duration = d1, .... (tn,dn).
Does anyone know how to accomplish that?
I've ended with a solution adding chapters to a video file instead of using metadata.
I looked at available libraries, took mpv4lib.
The library currently is not compiled for iOS, therefore, I ported the source project into static library for iOS platform.
That library allows to add custom "atoms" to mp4 file, and one of them is Quick Time text track, containing chapters.
I do similar with that post
The library is located here.
My understanding currently is that:
CameraUI
I can use the CameraUI to access the built in camera for MediaType.VIDEO and that delegates to the built-in video camera app and lets me record a video. My app does that now.
When I stop recording and click the "Use" button, I am returned to my app and theoretically I have a valid MediaPromise.
iOS does -not- provide a valid/usable url/filename to the recorded video (or to photos) and so I would have to use a Loader to bring-in/use/access the 'recorded' video... AND... iOS does not actually create a file anywhere on the device, most importantly, in the Camera Roll where one would expect by the normal behavior when uses the system native camera/video app.
The documentation says that the Loader can load various image types and SWFs but nothing about video data, so I conclude from that that I cannot actually use the CameraUI to generate a valid MediaPromise that I can then pass to a Loader class or similar to read in the information created by the system camera and then manipulate (upload, save to applicationStorageDirectory, and/or display in one of the two video player components available in the API).
CameraRoll
I can have video entities in the iOS Camera Roll but the AS3/Air3.5 CameraRoll class won't let me view/access/reference them in any way.
Normal File I/O
All my attempts to use the Air3.5 File classes to browse to the storage location of the iOS Camera Roll have been rebuffed.
------- Questions -------
Am I correct in believing that there is a way to take video but no way to use the video that's been captured. (No way to use the resulting MediaPromise successfully).
I believe you can take video and access it using Android, but there's nothing in the documentation that says that you cannot using iOS.
Am I correct in believing that iOS sandboxes apps so that they cannot browse to video/photo storage using standard File I/O, but only through the apparently non-workable means I've tried (CameraUI & CameraRoll)
Am I wrong to think that these should be rather obvious NEEDS that one can achieve using the XCode Objective C++ etc route but the AIR Mobile Framework does not allow either because of Apple blocking functionality or because Adobe has failed to meet reasonable expectations?
One item of ironic note to convey. If I use the iOS system camera app to record a video, a thumnail of that video then appears in the Gallery/Camera Roll, and of course, I can share it or view it, or whatever... If I use AIR's CameraRoll.browseForImage(), provided I haven't used the camera to take another image, when it shows me the folder where the pictures are stored, the folder icon uses the thumbnail of the last object added... in this case, the video I took, but if I then enter the folder, the video cannot be found. It's teasing us. It knows it's there, but it is apparently forbidden fruit.
I can't answer all your questions, so this entry may not be acceptable, but I found this page while searching a solution for some the problems you described and thought that someone else may find this answer (partially) useful.
To save the movie you just took you need to open and read the data from the promise.
The iOS won't save the file anywere, so the MediaPromise.file is always null.
This is my solution to the problem:
private var camera:CameraUI;
private var dataInput:IDataInput;
public function recordVideo():void
{
// Start the camera and ask for a video
camera = new CameraUI();
camera.addEventListener(MediaEvent.COMPLETE, onCameraComplete);
camera.launch(MediaType.VIDEO);
}
private function onCameraComplete(event:MediaEvent):void
{
// event.data is a MediaPromise and MediaPromise.open() returns a IDataInput
// Let's cast it to a dispatcher and check when it's complete
dataInput = event.data.open();
var dispatcher:IEventDispatcher = IEventDispatcher(dataInput);
dispatcher.addEventListener(Event.COMPLETE, onDataInputComplete);
}
private function onDataInputComplete(event:Event):void
{
// We can do whatever we want with the data, so we'll store it in a File
var file:File = new File();
var bytes:ByteArray = new ByteArray();
var stream:FileStream = new FileStream();
// Reading the data from the opened MediaPromise
dataInput.readBytes(bytes);
stream.open(file, FileMode.WRITE);
stream.writeBytes(bytes, 0, bytes.bytesAvailable);
stream.close();
}
Also, I'm still looking for a way to put the movie in the CameraRoll
I want to preload multiple audio files. To do this, I tried to create multiple Audio elements in JavaScript.
function loadAudio(){
audio1 = new Audio();
audio1.addEventListener('canplaythrough', isLoaded, false);
audio1.src = 'assets/audio/Maid with the Flaxen Hair.mp3';
audio1.load();
}
function isLoaded(){
audio1.removeEventListener('canplaythrough', isAppLoaded);
alert('maid');
alert('start audio 2');
audio2 = new Audio();
audio2.addEventListener('canplaythrough', isLoaded2, false);
audio2.src = 'assets/audio/Kalimba.mp3';
audio2.load();
}
function isLoaded2(){
alert('kalimba');
}
I only get the first alert, the second one never works.
I found that I can only play one sound at a time, but can I also only load one? Does the script need another user input for every new Audio object I create? Or does anyone have another way to create a preloader for audio?
this could have to do with the limitations on autoplaying (and, as far as i know autoloading) audiofiles on ios-devices (see here: Limitations of HTML5 Audio on iOS 4?).
In short: You cannot programmatically start audio-playback on ios devices, this is only allowed from within event-handlers for trusted (=initiated by the user) events.
Yo can play multiple audio on IOS device
using following way
$("#btn").on("click",function(){
alert("audio clicked");
var aud=new Audio();
aud.src="music.mp3";
aud.play();
var aud1=new Audio();
aud1.src="intro.mp3";
aud1.play();
})
The above code play multiple audio on device