I am working on video player using video node of Scene Graph Component. My issue is when i set seek field like
m.video.seek = 20 it's start playing from 15 seconds or 18 seconds but not from exact position 20 seconds. My code is...
inner = createObject("RoSGNode", "ContentNode")
inner.url = "http://-------------.m3u8"
inner.streamformat = "hls"
inner.SwitchingStrategy = "full-adaptation"
Video file format is m3u8 and using ui_resolutions=fhd in manifest file of roku app.
Is this issue related to stream format or others? Please help me.
This is correct behavior you have "hls" streamformat, this is format specific, hls video stream is divided into chunks, so when you set seek, video will start from chunk start not from the middle of this chunk.
I solved this issue by setting video component attribute seekMode to "accurate"
<Video id="videoPlayer" visible="true" translation="[0, 0]" width="1920" height="1080" seekMode = "accurate" enableTrickPlay="true" enableUI="false"/>
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.
I've developed an Android app that allows user to create boomerang-alike mp4 video. This video consists of 10 still images being played back and forth quite fast. I know that such video (boomerang effect) can be easily looped from single video file while playing it, but I really need to create a mp4 video that would essentially contain already prepared boomerang video. The output video can be downloaded and played by user on any external player (over which obviously I don't have any control).
For that purpose currently I create a video from images in a loop. The loop starts from 1st picture and goes to 10th picture with 0.25 sec delay between frames, then goes back from 10th to 1st including delay. And there is 5 of those loops, which essentialy means creating a single video from 5 * 10 * 2 = 100 images. I know it's kinda ridiculous, so the time that it takes to prepare this video is riduculous as well (around 1:40 min).
What solution could you recommend assuming that the output video really has to consist of 5 loops back-and-forth? I've thought about creating single loop video (20 pictures) and then create final output video by concatenating it 5 times. But could it be any good? I'm trying to find an efficient yet understandable for a beginner Android programmer way.
You can use FFMPEG to Create boomerang like video below is a simple example code :-
ffmpeg -i input_loop.mp4 -filter_complex "[0]reverse[r];[0][r]concat,loop=5:250,setpts=N/55/TB" output_looped_video.mp4
1.5 seconds of video file as input named input_loop.mp4
n loop=5:250, 5 is number of loops, 250 is frame rate x double length of clip. The setpts is applied to avoid frame drops, and the value 25 should be replaced with the framerate of the clip
setpts=N/<VALUE>/TB" you can alter value according to your need
increase value to speed up boomerang effect
decrease value to slow down boomerang effect
I was looking for a way to create a boomerang video and found a pretty cool example of how to do it on GitHub.
You create the video by using the FFMPEG library org.bytedeco.javacpp-presets to clone the frames.
https://github.com/trantrungduc/boomerang-android
This is the place in code in which you can customize the video loop:
for (int k = 0; k < 3; k++) {
for (Frame frame1 : loop) {
frecorder.record(frame1);
}
for (int i=loop.size()-1;i>=0;i--){
frecorder.record(loop.get(i));
}
}
I am transcoding videos based on the example given by Google (https://android.googlesource.com/platform/cts/+/master/tests/tests/media/src/android/media/cts/ExtractDecodeEditEncodeMuxTest.java)
Basically, transocding of MP4 files works, but on some phones I get some weird results. If for example I transcode a video with audio on an HTC One, the code won't give any errors but the file cannot play afterward on the phone. If I have a 10 seconds video it jumps to almost the last second and you only here some crackling noise. If you play the video with VLC the audio track is completely muted.
I did not alter the code in terms of encoding/decoding and the same code gives correct results on a Nexus 5 or MotoX for example.
Anybody having an idea why it might fail on that specific device?
Best regard and thank you,
Florian
I made it work in Android 4.4.2 devices by following changes:
Set AAC profile to AACObjectLC instead of AACObjectHE
private static final int OUTPUT_AUDIO_AAC_PROFILE = MediaCodecInfo.CodecProfileLevel.AACObjectLC;
During creation of output audio format, use sample rate and channel count of input format instead of fixed values
MediaFormat outputAudioFormat = MediaFormat.createAudioFormat(OUTPUT_AUDIO_MIME_TYPE,
inputFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE),
inputFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT));
Put a check just before audio muxing audio track to control presentation timestamps. (To avoid timestampUs X < lastTimestampUs X for Audio track error)
if (audioPresentationTimeUsLast == 0) { // Defined in the begining of method
audioPresentationTimeUsLast = audioEncoderOutputBufferInfo.presentationTimeUs;
} else {
if (audioPresentationTimeUsLast > audioEncoderOutputBufferInfo.presentationTimeUs) {
audioEncoderOutputBufferInfo.presentationTimeUs = audioPresentationTimeUsLast + 1;
}
audioPresentationTimeUsLast = audioEncoderOutputBufferInfo.presentationTimeUs;
}
// Write data
if (audioEncoderOutputBufferInfo.size != 0) {
muxer.writeSampleData(outputAudioTrack, encoderOutputBuffer, audioEncoderOutputBufferInfo);
}
Hope this helps...
If original CTS tests fail you need to go to device vendors and ask for fixes
I have some audio data (raw AAC) inside a byte array for playback. During playback, I need to get its volume/amplitude to draw (something like an audio wave when playing).
What I'm thinking now is to get the volume/amplitude of the current audio every 200 milliseconds and use that for drawing (using a canvas), but I'm not sure how to do that.
.
.
.
.
** 2011/07/13 add following **
Sorry just been delayed on other project until now.
What I tried is run the following codes in a thread, and playing my AAC audio.
a loop
{
// int v=audio.getStreamVolume(AudioManager.MODE_NORMAL);
// int v=audio.getStreamVolume(AudioManager.STREAM_MUSIC);
int v=audio.getStreamVolume(AudioManager.STREAM_DTMF);
// Tried 3 settings above
Log.i(HiCardConstants.TAG, "Volume - "+v);
try{Thread.sleep(200);}
catch(InterruptedException ie){}
}
But only get a fixed value, not dynamic volume...
And I also found a class named Visualizer, but unfortunately, my target platform is Android 2.2 ... :-(
Any suggestions are welcome :-)
After days and nights, I found that an Android app project called ringdroid
can solve my problem.
It helps me to get an audio gain value array, so that I can use to to draw my sound wave.
BTW, as my experience, some .AMR or .MP3 can't be parsed correctly, due to too low bitrate...
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.