Investigating the Java code of the lib, I found no way to save playing video somewhere. However, the VLC core has such capabilities, according to this doc, you can duplicate the stream and save it, redirecting it right to the file.
I thought we could supply the corresponding arguments while creating an instance of lib, so I tried to add an option when initializing library in libvlcjni.c like that:
"--sout=duplicate{dst=standard{access=file,mux=ts,dst=/storage/emulated/0/example.mp4},
dst=display}"
but seems it's not working. Any other ideas?
You can concurrently save a playing video to a file using libvlc (at least the following worked for me):
final ArrayList<String> args = new ArrayList<>();
args.add("-vvv");
mLibVLC = new LibVLC(this, args);
mMediaPlayer = new MediaPlayer(mLibVLC);
<code associating surface for display...>
Media media = new Media(mLibVLC, Uri.parse(SAMPLE_URL));
media.addOption(":sout=#duplicate{dst=file{dst=" + <file name> + "},dst=display}");
mMediaPlayer.setMedia(media);
mMediaPlayer.play();
Guess, currenty there is no way to do it by means of libvlc.
However, guys have plans for this feature, see their milestones at gitlab
Related
I'm using xamarin.android to create an android application. for working on the output of recorded audios in android for changing its pitch and the other thing with NWaves package, I need to change its format to .wav. I tried to use many audio convertors but all of them threw exceptions, but it should work with FFmpeg. However, I used this code but it doesn't generate any file.
List<string> cmd = new List<string>();
cmd.Add("ffmpeg");
cmd.Add("-i");
cmd.Add("/storage/emulated/0/Android/data/com.companyname.pushersvc/demo.3GP");
cmd.Add("/storage/emulated/0/Android/data/com.companyname.pushersvc/test.wav");
string cmdParams = string.Join(" ", cmd);
await FFMpeg.Xamarin.FFMpegLibrary.Run(
Application.Context,
cmdParams
);
return new FileInfo(path);
I read this and FFMpeg docs, but all of them used .mp4 convertor.
I also read ffmpeg doc for audio converting which you can see the code, which is not working
I want to show subtitles with ExoPlayer 2 . users can choose between languages (English,German, or Arabic) . Video links are HLS (.m3u8) and subtitles are .str files .
I couldn't find any samples to do this.
is there any sample?
The link I added as a comment to your original post will be how you'll build the UI around text track selection. Then to actually get the tracks to be added to your mp4 file (or whatever the format is), you'll want to use a MergingMediaSource. The simple version looks like so:
MediaSource videoSource = new ExtractorMediaSource(videoUri, ...);
MediaSource subtitleSource = new SingleSampleMediaSource(subtitleUri, ...);
// Plays the video with the sideloaded subtitle.
MergingMediaSource mergedSource = new MergingMediaSource(videoSource, subtitleSource);
You can merge multiple subtitle tracks into the video source. Many different file formats are accepted.
I got that particular code sample from this blog post - but I believe that same code is also in the ExoPlayer documentation. That code block combined with the sample code that I link to in my other answer here should be enough to get you some subtitles.
Please let me know if that works for you.
I'm trying to implement Google Speech API in Android by following this demo: https://github.com/GoogleCloudPlatform/android-docs-samples
I was able to successfully reproduce the example in my app by using the given "audio.raw" file located in R.raw, and everything works perfectly. However, when I try to use my own audio files, it returns "API successful" without any transcription text. I'm not sure if it has to do with the files' path or the encoding, so I'll include information on both just in case.
Encoding
My audio files are obtained by recording a voice through MediaRecorder. These are the settings:
myAudioRecorder = new MediaRecorder();
myAudioRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
myAudioRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
myAudioRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_WB);
myAudioRecorder.setAudioSamplingRate(16000);
myAudioRecorder.setAudioEncodingBitRate(16000);
myAudioRecorder.setAudioChannels(1);
myAudioRecorder.setOutputFile(outputFile);
SpeechService's recognizeInputStream() function in the API:
mApi.recognize(
RecognizeRequest.newBuilder()
.setConfig(RecognitionConfig.newBuilder()
.setEncoding(RecognitionConfig.AudioEncoding.AMR_WB) //originally it was LINEAR16
.setLanguageCode("en-US")
.setSampleRateHertz(16000)
.build())
.setAudio(RecognitionAudio.newBuilder()
.setContent(ByteString.readFrom(stream))
.build())
.build(),
mFileResponseObserver);
Encoding guidelines by Google: https://cloud.google.com/speech/docs/best-practices
From what I understand, I can use AMR_WB and 16kHz instead of the default LINEAR16, I'm just not sure if I'm doing it right.
Path
This is the example that is fully working (with the audio file from the repo):
mSpeechService.recognizeInputStream(getResources().openRawResource(R.raw.audio));
However, none of the following options work, even with the exact same file:
InputStream inputStream = new URL("[website]/test/audio.raw").openStream();
mSpeechService.recognizeInputStream(inputStream);
Neither:
Uri uri = Uri.parse("android.resource://[package]/raw/audio");
InputStream inputStream = getActivity().getContentResolver().openInputStream(uri); //"getActivity()" because this is in a Fragment
mSpeechService.recognizeInputStream(inputStream);
To be clear, the result on the above paths is the same as on my custom audio files: "API successful" with no transcription. One of the options I have tried for my custom audio files, with the same thing happening, is this:
FileInputStream fis = new FileInputStream(filePath);
mSpeechService.recognizeInputStream(fis);
The only reason I'm not 100% sure the problem is in the path is because if the API is returning with success, then the file was found in the specified path. The problem should be the encoding, but then it's weird that the same file ("audio.raw") sent in different ways produces different results.
Anyway, thank you in advance! :)
EDIT:
To be clear, it's not that it returns an empty string in the transcription. It just never enters the "onSpeechRecognized" function that also exists in the demo, so no transcription is given.
I'm using mp4parser to mux h264 and aac file which are re-encoded from orginal video file,how can I write the metadata of the original video to the new mp4 file? Or is there a common method to write metadata to mp4 file?
metadata and MP4 is a really problem. There is no generally supported specification. But this is only one part of the problem.
Prob (1): When to write metadata
Prob (2): What to write
Prob (1) is relatively easy to solve: Just extend the DefaultMp4Builder or the FragmentedMp4Builder on your own and override the
protected ParsableBox createUdta(Movie movie) {
return null;
}
with something meaningful. E.g.:
protected ParsableBox createUdta(Movie movie) {
UserDataBox udta = new UserDataBox();
CopyrightBox copyrightBox = new CopyrightBox();
copyrightBox.setCopyright("All Rights Reserved, me, myself and I, 2015");
copyrightBox.setLanguage("eng");
udta.addBox(copyrightBox);
return udta;
}
some people used that to write apple compatible metadata but even though there are some classes in my code I never really figured out what works and what not. You might want to have a look into Apple's specification here
And yes: I'm posting this a year to late.
It seems that the 'mp4parser' library (https://code.google.com/p/mp4parser/), supports writing Metadata to mp4 files in Android. However, I've found there's little-to-no documentation on how to do this, beyond a few examples in their codebase. I've had some luck with the following example, which writes XML metadata into the 'moov/udta/meta' box:
https://github.com/copiousfreetime/mp4parser/blob/master/examples/src/main/java/com/googlecode/mp4parser/stuff/ChangeMetaData.java
If you consider the alternatives you might want to look at JCodec for this purpose. It now has the org.jcodec.movtool.MetadataEditor API (and a matching CLI org.jcodec.movtool.MetadataEditorMain).
Their documentation contains many samples: http://jcodec.org/docs/working_with_mp4_metadata.html
So basically when you want to add some metadata you need to know what key(s) it corresponds to. One way to find out is to inspect a sample file that already has the metadata you need. For this you can run the JCodec's CLI tool that will just print out all the existing metadata fields (keys with values):
./metaedit <file.mp4>
Then when you know the key you want to work with you can either use the same CLI tool:
# Changes the author of the movie
./metaedit -f -si ©ART=New\ value file.mov
or the same thing via the Java API:
MetadataEditor mediaMeta = MetadataEditor.createFrom(new
File("file.mp4"));
Map<Integer, MetaValue> meta = mediaMeta.getItunesMeta();
meta.put(0xa9415254, MetaValue.createString("New value")); // fourcc for '©ART'
mediaMeta.save(false); // fast mode is off
To delete a metadata field from a file:
MetadataEditor mediaMeta = MetadataEditor.createFrom(new
File("file.mp4"));
Map<Integer, MetaValue> meta = mediaMeta.getItunesMeta();
meta.remove(0xa9415254); // removes the '©ART'
mediaMeta.save(false); // fast mode is off
To convert string to integer fourcc you can use something like:
byte[] bytes = "©ART".getBytes("iso8859-1");
int fourcc =
ByteBuffer.wrap(bytes).order(ByteOrder.BIG_ENDIAN).getInt();
If you want to edit/delete the android metadata you'll need to use a different set of fucntion (because it's stored differently than iTunes metadata):
./metaedit -sk com.android.capture.fps,float=25.0 file.mp4
OR alternatively the same through the API:
MetadataEditor mediaMeta = MetadataEditor.createFrom(new
File("file.mp4"));
Map<String, MetaValue> meta = mediaMeta.getKeyedMeta();
meta.put("com.android.capture.fps", MetaValue.createFloat(25.));
mediaMeta.save(false); // fast mode is off
hi guys i read many example about play video in video view, but no one work for me, i get this error:
java.io.FileNotFoundException: /android.resource:/frt.com.maint/2130968576 (No such file or directory)
this is my code-------------------------------------------------------------------------:
FileInputStream fi = new FileInputStream("android.resource://frt.com.maint/" + R.raw.videointro);
MediaPlayer pl = new MediaPlayer();
pl.setDataSource(fi.getFD());
pl.prepare();
pl.start();
MediaPlayer don't have method setVideoURI, i use the first solution that you give me but i still get same error, after i use this code with videoview:
Uri video = Uri.parse("android.resource://frt.com.maint/videointro");
vidview_gdf.setVideoURI(video);
vidview_gdf.start();
but i get an error with message "you can not play the video"
p.s: additional info: introvideo.mp4 - 7 MB
You're trying to use the ID of the resource, which is just an int index.
Use the filename instead:
fi = new FileInputStream("android.resource://frt.com.maint/nitrovideo");
Or better:
StringBuilder videoURIPath = new StringBuilder();
videoURIPath.append("android.resource://");
videoURIPath.append(getPackageName() + "/");
videoURIPath.append("raw/");
videoURIPath.append(videoFileName);
pl.setVideoURI(Uri.parse(videoURIPath.toString());
Where videoFileName is a string of the name of your file.
Are you doing this on emulator or actual device?
I had a bit of bad experience with H.264 encoded video before. Basically, I tried to play it on the first GalaxyTab but it didn't work. Turned out that GalaxyTab I had didn't support H.264.
So, I would advise you to make sure that the default video player can play this file before proceed further. If that's not the case for you then I'm not sure what's wrong. Your code looks fine to me.