I am developing a PhoneGap application that uses HTML5 Audio tag to run MP3 Audios. Although controls are on, but when the application is run on an Android phone the controls do not show up. All I can see is just the slider. In Ripple Emulator all works fine.
I am not interested in other controls but at least I should be able to display the timer.
Anyone can please suggest how can I do that.
Thanks!
Not sure whether i am right or wrong. few days back, i was struggled with integrating the audio and video tag for html5. Android browser doe'nt support the Audio/Video tag, for even i have given the controls for it, but then too it was not worked. What i done was, i used to define the script in-order to perform the mediafiles using Html5 tag.
String script = "<SCRIPT LANGUAGE=" + "JavaScript"
+ ">function playvideo(url){window.location=url;}</SCRIPT>";
include the above script in you html5, and let me know whether it works or not.
Note:
I used native activity for this.
I have explored and successfully replaced html5 audio with MediaElement.js
Here is my Audio tag:
<audio autoplay="autoplay" id="audioplayer" controls="true">
<source src="none" type="audio/mp3">
****
</audio>
And the following script simply converts the HTML5 audio player to MediaElement player with all the controls that I wanted to see:
$('audio').mediaelementplayer({
//audio { width: 250px; margin:10px;}
defaultAudioWidth: 300,
// default if the user doesn't specify
defaultAudioHeight: 30,
// width of audio player
audioWidth: 300,
// height of audio player
audioHeight: 30,
// initial volume when the player starts
startVolume: 1.0,
// useful for <audio> player loops
loop: false,
// enables Flash and Silverlight to resize to content size
enableAutosize: true,
// the order of controls you want on the control bar (and other plugins below)
features: ['playpause','progress','current','duration'],
// Hide controls when playing and mouse is not over the video
alwaysShowControls: false,
// force iPad's native controls
iPadUseNativeControls: false,
// force iPhone's native controls
iPhoneUseNativeControls: false,
// force Android's native controls
AndroidUseNativeControls: false,
// forces the hour marker (##:00:00)
alwaysShowHours: false,
// show framecount in timecode (##:00:00:00)
showTimecodeFrameCount: false,
// used when showTimecodeFrameCount is set to true
framesPerSecond: 25,
// turns keyboard support on and off for this instance
enableKeyboard: true,
// when this player starts, it will pause other players
pauseOtherPlayers: true,
// array of keyboard commands
keyActions: []
});
So this is a fantastic solution if anyone is looking for a nice replacement of HTML5 Audio.
Related
My app requires to record a video to capture the IFrames only (and not the P/B frames).
I am making use of the Media Recorder to capture the video (Not using cameraX as I need HEVC and camerax is recording in H.264).
The 'MediaRecorder.MetricsConstants.VIDEO_IFRAME_INTERVAL' is set to 1, by default - hence I get an IFrame every 1 sec and the rest of the frames in a second are 'P'. I need the VIDEO_IFRAME_INTERVAL constant to be set to 0, inorder to make all the frames 'I'. I have tried different ways to set it. Any help would be much appreciated.
I have tried setting it this way:
mRecorder.metrics.deepCopy().apply {
this.putInt(MediaRecorder.MetricsConstants.VIDEO_IFRAME_INTERVAL, 0)
}
Even if I set it to '2', '5' or '10' it doesn't seem to be having an effect.
Im at the breaking point with this error. I developed a svelte webapp with an hls.js video player which I packaged in an android webview for Firesticks. The App works great except for one odd issue where after about 3-4 hours of playback the video freezes. I was able to catch some logs using adb.
The error does not happen in the usual hls.js onError handlers, but instead is being generated elsewhere. Cannot read properties of null (reading 'byteLength') is totally ambiguous but it is the best I've been able to get. Unfortunately the error only happens on the actual minified JS code and not on any browser debug builds.
Im at a total loss as to what could be causing this or how to even debug it. Maybe someone has experienced something like this in the past? Below is the video element in my svelte component and the hls.js initialization code.
<div class="playback-view" on:click|stopPropagation>
<video
bind:this={videoRef}
bind:currentTime={$ProgramTime}
on:ended={onPlaybackEnded}
bind:duration
bind:paused>
<track kind="captions">
</video>
const destroyHls = () => {
if (hls !== null && hls !== undefined){
hls.stopLoad()
hls.detachMedia()
hls.destroy()
}
}
const reloadSource = () => {
destroyHls()
if (videoRef !== null && videoRef !== undefined){
hls = new Hls({
// Audio codec for bitrate above 22hz
defaultAudioCodec: "mp4a.40.2",
//(seconds) If buffer < this value fragment will be loaded
// The "minimum" length of the buffer
maxBufferLength: 15,
backBufferLength: 1800,
// (seconds) The maximum length of the buffer
maxMaxBufferLength: 60,
// (bytes) The amount hls will try to load
// maxBufferSize: 120 * 1000 * 1000,
// (seconds) The amount to offset the stream by when stalling
// currentTime += (nb nudge retry -1)*nudgeOffset
nudgeOffset: 0.1,
// Number of nudges before BUFFER_STALLED_ERROR
nudgeMaxRetry: 3,
})
hls.attachMedia(videoRef)
hls.loadSource($Playback.playbackUrl)
hls.on(Hls.Events.ERROR, handleHLSError)
videoRef.play()
paused = false
}
}
After a comment suggested to check the buffer size. I decreased the backBufferLength and the maxMaxBufferLength. Now however I am faced with a new error.
"hlsError" {"type":"mediaError","parent":"main","details":"bufferAppendError","err":{"stack":"Error: Failed to execute 'appendBuffer' on 'SourceBuffer': The HTMLMediaElement.error attribute is not null.
This is failing to append to source buffer, but shouldn't hls.js be taking care of the clearing the buffer?
Unfortunately I was unable to figure out a consistently working set of settings for this issue. Changing HLS options simply resulted in different errors happening. In the end I basically did something similar to what #VC.One suggested.
I used the onerror methods of hls.js to detect fragLoadError and when it shows up I do a reload of the stream at that specific time. This means calling reloadSource as defined in the original question.
I don't feel amazing about this solution since it is only a bandaid, but it works rather reliably. At most you will get a 5 second freeze in the video playback every couple of hours.
I have an Android application which uses android.media.SoundPool to play audio cues for the user. It works as expected, but I'd like to be able to add effects to the playback (via android.media.audiofx.AudioEffect subclasses).
I understand how audio effects work on (e.g.) MediaPlayer, but I don't see how to use them with SoundPool. In particular, I'm not sure what to use for the session ID. (I happen to be using Xamarin Android because... reasons. So my example looks weird -- but I'm happy to adapt native Java or Kotlin answers!)
int session = ???; // What goes here?
var fx = new LoudnessEnhancer(session);
fx.SetTargetGain(2400);
fx.SetEnabled(true);
Pool.Play(soundID, 1.0F, 1.0F, 1, 0, 1.00F);
I tried using session ID 0, but (on my WT6000 running Android 7.1.1) it crashes in the LoudnessEnhancer ctor:
Java.Lang.RuntimeException: Cannot initialize effect engine for type: fe3199be-aed0-413f-87bb-11260eb63cf1 Error: -3
(and anyway, my understanding is that applying effects to session ID zero is deprecated).
I have a web page with an embedded inline YouTube video that I control using the API for iframe embeds. The web page shows a video along with associated text and allows the user to click on a text selection to hear/watch that portion of the video as many times as they want (good for learning a foreign language). I use the player.seekTo(seconds, allowSeekAhead) function to move forward and backward in the video.
The seekTo function works fine on my desktop (in Chrome, Firefox, Safari, and IE) as well as on my own Android phone (Samsung A5) in both the stock WebView browser as well as Chrome (video starts playing from the requested point), but when I tried it on some older Android phones (LG & Samsung), the video would start playing further back than the requested time (more than 1 second)
To understand what was happening, I set up a test page where I watched the video’s time (polled the player.getCurrentTime() function every 50ms), and when it reaches 10 seconds, I programmatically seekTo 5 seconds. On my phone as well as the desktop browsers the time goes to 5 seconds and then starts incrementing from there. On the older phones, the time will first go to 5 seconds, but then after half-a-second, jump back to 3.125 or so (there is a slight variation each time), and then the video starts playing from that point.
I checked the userAgent string for the different phones I was using and found that my phone was running Chrome/34.0, while the WebKit browser on the older phones were running Chrome/30.0. When I tried running the test using a Chrome browser on an older phone (Chrome/34), the timing worked correctly.
My question: Was the seekTo issue I’m seeing in older Android browsers a bug that was fixed (in which case I just tell people who want to use my site to use Chrome) or is seekTo working correctly in Chrome/34 a “bug” and when a new version of Chrome comes out, it will revert back to the old action (in which case, I should create some sort of kludgy work around)?
jsFiddle – I put my test page on jsFiddle test page, but while it will work on my desktop, it doesn’t run on my phone (jsfiddle.net/draft/) – not sure why it won’t run on a phone, but at least it will show the code I was using to test the timing. Update - the jsfiddle now runs on a phone for testing - I had the code starting the video, which is not allowed on mobile platforms - the user has to initiate the video.
var tag = document.createElement('script'),
first_time = true;
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '315',
width: '560',
videoId: 'sA0-QXbLnaE',
playerVars: {
'autoplay': 0,
'controls': 0,
'showinfo': 0,
'hl': 'en_US',
'playsinline': 1,
'rel': 0,
'modestbranding': 0
},
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
function monitorVideoTiming() {
var player_time = player.getCurrentTime(),
tmp_string;
if ((player_time > 10) && (first_time === true)) {
first_time = false;
// player.pauseVideo();
player.seekTo(5, true);
// player.playVideo();
}
if ((!first_time) && (player_time < 11)) {
tmp_string = $("#time_report").html();
tmp_string = tmp_string + player_time.toFixed(3) + "<br />";
$("#time_report").html(tmp_string);
}
};
function onPlayerReady(event) {
event.target.playVideo();
}
function onPlayerStateChange(event) {
if (event.data === 1) {
setInterval(monitorVideoTiming, 50);
}
}
Note on key frames – I doubt this is a frame issue, as seekTo goes to the right point on Chrome/34, but backs up on Chrome/30 (the only two versions I have access to for testing), so the variation seems to be in the Chrome version.
Android : Phonegap has javasript functions to to play,pause,resume & stop the media player. Is there any way to control the volume(increase/decrease) by javascripst function.
1.phonegap.js file included
in html page :
<html>
<head> <script>
var my_media = null;
var mediaTimer = null;
function playAudio(src) {
my_media = new Media(src, onSuccess, onError);
my_media.play();
....
}
</script> </head> <body>
Play Audio
</body> </html>
in java class :
...
super.loadUrl("file:///android_asset/www/testmus.html");
I know this question is fairly old, but I came across it looking for something else.
There is a newish and not well-documented function on the PhoneGap Media class for Android:
setVolume()
So using the example above:
// level is a value from 0-100
var level = 50;
my_media.setVolume(level);
It's not heavily documented because I believe it's only on Android.
This is old, but as we were just solving this issue, I thought I'd put it up here.
The cordova my_media.setVolume(level); doesn't actually set the master volume of your audio stream, it just sets the volume of your audio asset relative to the overall audio stream's volume. For instance, if I have my device's music player stream set to half of the maximum, and I am playing my audio into the music player stream, then the loudest I can ever make it is half of maximum volume. For our uses, this was not enough.
To get around this, you can create an audio slider for your specific audio stream, hide it, and then programmatically set the slider's volume. This was figured out for ios and explained here -iOS 7: MPMusicPlayerController volume deprecated. How to change device volume now?
The code to create controllable audio sliders using cordova was originally done for ios, and then it was forked to Android. I would post the links, but I'm link-limited due to my non-existent reputation.
We combined these two, added in the ios volume control code, and then ported that over to Android as well so that there is now a cordova library to allow for Andoid and iOS music stream volume control here - https://github.com/shibbs/VolumeSlider
We have created a pull request to merge our version of the audio controller in with the devgeeks cordova volume controller code, but for the time being, the place to get it will be from the shibbs/ linked above.
A code snippet showing how you would go about it is :
my_media = new Media(soundFile, onSuccess, onError); //create the media object
my_media.setVolume(1.0); //set your volume to w/e you want, we maxed it
volumeSlider = plugins.volumeSlider; //create the volume slider object
volumeSlider.createVolumeSlider(10,350,300,30); // origin x, origin y, width, height
volumeSlider.setVolumeSlider(1.0); //set your volume slider value to between 0 and 1
volumeSlider.resetVolumeSlider(); //this will reset the device volume to whatever it was set to when you created the volumeSlider.
You would have to do what (I assume) phonegap does and use a Javascript bridge to the existing Java functions that control the volume. Volume control is in adjustVolume and adjustStreamVolume(): you can add custom javascript handlers as shown here.