Locating and playing video files in Processing - java

I'm pretty new to programming using Processing, and cannot find a way to have Processing open and play a video file. I have looked at a few previous questions regarding getting Processing to play videos using Java, but every time I try the code, I get a RuntimeException: Could not load movie file x. I have tried storing the video in different locations on my computer and with different resolutions and encoding, with the same result each time. Here is the code I believe is the closest to working:
import processing.video.*;
Movie myMovie;
void setup() {
fullScreen();
myMovie = new Movie(this, "hollywood_test.mp4");
myMovie.play();
}
void draw() {
image(myMovie,0,0);
}
void movieEvent(Movie m) {
m.read();
}
If anybody knows how I can get Processing to look in the right place to find the video, or if I've made a mistake with the code, it would be greatly appreciated.

The easy way here might be to just open a fileSelector
void fileSelected(File selection) {
if (selection == null) {
println("Window was closed or the user hit cancel.");
} else {
//not sure about the loadimage for a mp4
myMovie= loadImage (selection.getAbsolutePath());
println("User selected " + selection.getAbsolutePath());
}
}
void load_image(){
selectInput("Select a file to process:", "fileSelected");
}
void setup{
fullscreen();
load_image();
myMovie.play();
}
void draw(){
load_image();
image(myMovie,0,0);
}

Related

Java download causes lag spike with really small files

EDIT: I've decided to remove the Minecraft tag. While this IS a Minecraft mod's code, the code I'm having trouble with has to do with functions within core Java, and not anything in Minecraft itself.
So, I posted a question last night about me writing a function of a Minecraft mod to allow us to implement our own capes and thanks to some of you I was able to get that working. I've crammed down the code from there and found a way to make it as small as possible while producing the same outcome. I've also found out how to read files directly from a download stream instead of copying the file. Great? Well, no. Now that I'm able to properly test everything and read my files, I've run into another problem. While everything works fine, it causes a lag spike of upwards to 2-4 seconds whenever my code is running. I've looked around and found issues about slow downloads, but nothing about the application completely freezing for a small period of time. Since this is run whenever a player first appears on-screen, this can get repetitive. I'm trying to fix the code and have rearranged it countless times in different ways and it just won't go away.
Here's the code. In short, it checks if the player has an official Mojang cape on their account. If they don't, then instead it runs my code to check if they have one of our custom capes, and exactly when this is run, is when the game has a lag spike. Note that if the player has a cape from Mojang my code is never run and I've tried disabling my code and just running the code that downloads their Mojang cape for use, so I know that part doesn't cause lag, it's specifically just my code. Even if they don't have a custom cape under my code it always causes lag. I can't think of why; the files are very small!
... While writing this, I decided to test something, and so I disabled the player.cloakUrl variable setting lines in my getCustomCapes method. Surely enough the lag still happened so I reckon the lag is caused by the lines that check if the player UUID matches one in the downloaded .txt files. I'm confident the lines of code that check and download from the .txt files are the culprits to the lag here. Note that I'm reading from streamed online files rather than saving them to the computer permanently since they don't need to. They're read every time this code is called and it needs to stay that way.
Without further ado here's the code.
EDIT: I've tried to add .close() commands to the streams with no success.
public static void getSkin(final GameProfile profile, EntityPlayer player) {
final Map<Type, MinecraftProfileTexture> map = Maps.<Type, MinecraftProfileTexture>newHashMap();
// (Here's where some skin-related code would be but I cut it out for easier reading,
// it has nothing to do with this situation so don't worry about that.)
if (map.containsKey(Type.CAPE))
{
MinecraftProfileTexture texture = (MinecraftProfileTexture)map.get(Type.CAPE);
player.cloakUrl = texture.getUrl();
return;
} else {
getCustomCapes(profile, player); //Commenting this fixes the lag, proving it's my code that causes it.
}
}
public static void getCustomCapes(final GameProfile profile, EntityPlayer player) {
InputStream staff;
InputStream contest;
try {
contest = new URL("https://www.dropbox.com/s/kvvkfk6emms3qg5/contest.txt?dl=1").openStream();
StringWriter contestUUIDs = new StringWriter();
IOUtils.copy(contest, contestUUIDs, StandardCharsets.UTF_8);
if (contestUUIDs.toString().contains(profile.getId().toString()))
{
player.cloakUrl = "https://www.dropbox.com/s/a4d3agty57sd4a8/contest.png?dl=1";
// Commenting out the above line doesn't seem to help any, as stated before.
return;
}
staff = new URL("https://www.dropbox.com/s/q6f4729i2zu02nz/staff.txt?dl=1").openStream();
StringWriter staffUUIDs = new StringWriter();
IOUtils.copy(staff, staffUUIDs, StandardCharsets.UTF_8);
if (staffUUIDs.toString().contains(profile.getId().toString()))
{
player.cloakUrl = "https://www.dropbox.com/s/42jn5r7fs6k5f4l/staff.png?dl=1";
// Commenting out the above line doesn't seem to help any, as stated before.
return;
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
What an old thread, huh? So, after getting a little more experience I decided to head back to this to say I've found the solution. Here's how I fixed it: Thread magic! ug_ suggested this to me a while ago it seems, but I simply didn't understand at the time. I used some methods to start a thread with special variables that set the player's properties when it's done, removing the lag. Also, I rewrote the way the cape .txts work to be a little more efficient. You may notice there's one file now, and that one controls everything instead of each list having its own file. Here's my code. First, the above get skin methods have been scraped out almost entirely, and I added a new one since creating a GameProfile sends requests to Mojang's API, causing a little bit of lag, so I made it so this thread can also generate profiles:
public static void getSkin(final GameProfile profile, EntityPlayer player) {
ThreadFetchSkins skinThread = new ThreadFetchSkins();
skinThread.start(player, profile, mc);
}
public static void getSkinFromUUIDAndName(UUID uuid, String username, EntityPlayer player) {
ThreadFetchSkins skinThread = new ThreadFetchSkins();
skinThread.start(uuid, username, player, mc);
}
And then, here's the thread.
public class ThreadFetchSkins extends Thread {
public static TreeMap<UUID, String> customCapes = new TreeMap<UUID, String>();
private EntityPlayer thePlayer;
private GameProfile theProfile;
private Minecraft mc;
private boolean createProfile = false;
private UUID id;
private String name;
public ThreadFetchSkins() {
setName("Cape data download thread");
setDaemon(true);
}
public void run() {
if(createProfile) {
theProfile = new GameProfile(id, name);
}
final Map<Type, MinecraftProfileTexture> map = Maps.<Type, MinecraftProfileTexture>newHashMap();
theProfile.getProperties().clear();
theProfile.getProperties().putAll(SkinManager.getProfileProperties(theProfile));
map.putAll(mc.sessionService.getTextures(theProfile, false));
//Removed "secure" textures grab
if (map.containsKey(Type.SKIN))
{
MinecraftProfileTexture texture = (MinecraftProfileTexture)map.get(Type.SKIN);
thePlayer.skinUrl = texture.getUrl();
String grab = texture.getMetadata("model");
// Currently returns null for steve skin
thePlayer.modelAlex = !(grab == null);
thePlayer.worldObj.obtainEntitySkin(thePlayer);
}
if (map.containsKey(Type.CAPE))
{
MinecraftProfileTexture texture = (MinecraftProfileTexture)map.get(Type.CAPE);
thePlayer.cloakUrl = texture.getUrl();
thePlayer.worldObj.obtainEntitySkin(thePlayer);
}
else {
grabCustomCapes();
}
}
public void grabCustomCapes() {
try {
URL capeDownload = new URL("https://www.dropbox.com/s/q6f4729i2zu02nz/capes.txt?dl=1");
String capeFolder = Minecraft.getMinecraftDir().getPath() + "/NFCCapes";
FileUtils.forceMkdir(new File(capeFolder));
FileUtils.copyURLToFile(capeDownload, new File(capeFolder + "/capes.txt"));
InputStream fileOS = new FileInputStream(capeFolder + "/capes.txt");
BufferedReader buf = new BufferedReader(new InputStreamReader(fileOS));
String line = buf.readLine();
customCapes.clear();
while(line != null) {
String[] data = line.split(";");
customCapes.put(UUID.fromString(data[1]), data[2]);
line = buf.readLine();
}
fileOS.close();
FileUtils.getFile(capeFolder).delete();
if(customCapes.get(theProfile.getId()) != null) {
thePlayer.cloakUrl = customCapes.get(theProfile.getId());
thePlayer.worldObj.obtainEntitySkin(thePlayer);
}
} catch (MalformedURLException e) {
e.printStackTrace();
return;
} catch (IOException e) {
e.printStackTrace();
return;
}
}
public void start(EntityPlayer player, final GameProfile profile, Minecraft minecraft) {
thePlayer = player;
theProfile = profile;
mc = minecraft;
super.start();
}
public void start(UUID uuid, String username, EntityPlayer player, Minecraft minecraft) {
id = uuid;
name = username;
thePlayer = player;
mc = minecraft;
createProfile = true;
super.start();
}
}

How can i make parallel or concurent API calls?

I am building an Android app (my first app actually) and it's about getting similar tracks to the one you searched for. I am using retrofit2 with rxJava and gson for my calls.
For each track i found i add the corresponding image provided by the response in an imageview, but this image is not the actual album image, it's just an image of the band. I want to have the album image which i can get from the API if i do an album search.
So is there a way to make a API call that returns the album info for each track without losing to much time loading? I want these calls to happen in parallel with each other so as to be less visible to the "user" (me).
This is the code that i use to search for the similar tracks:
private void loadSimilarTracks() {
String mbid = selectedTrack.getMbid();
String artist = selectedTrack.getmArtist();
String track = selectedTrack.getName();
searchService = new LastFMSearchService();
Flowable<List<TrackSimilar>> fetchDataObservable = null;
if(!mbid.equals("")) {
fetchDataObservable = searchService.getSimilarTracks(mbid);
}
else{
fetchDataObservable = searchService.getSimilarTracks(artist, track);
}
mCompositeSubscription.add(fetchDataObservable
.timeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new DisposableSubscriber<List<TrackSimilar>>() {
#Override
public void onNext(List<TrackSimilar> tracks) {
mTracks = tracks;
similarTrackAdapter.setTrackList(tracks);
}
#Override
public void onError(Throwable e) {
Toast.makeText(getActivity(), "API CALL ERROR", Toast.LENGTH_SHORT).show();
}
#Override
public void onComplete() {
resultsView.setVisibility(View.VISIBLE);
}
})
);
}
P.S i am using the lastFM api for my info.
Thanks in advance for any response.
Your code is good, one thing that you can do is that you can segment your code into multiple functions instead of a single one and run them as separate threads.
One function that makes api calls to search for similar tracks and other to get the image and trust me that significantly improves the response. Hope it helps..

Sound not playing first time even if Libgdx says it's loaded into memory

I'm using Libgdx and AssetManager to load assets into memory. First I thought that something is wrong with my project so I made a new clean one, and the problem persists.
The Sound is not playing even if I use "IsLoaded" method and is not playing the first time (if you jump really quick into the game). The sound is small , like 40KB, and this happens only on Android (works on Desktop/iOS). The device I'm testing on Android is HTC One M7 with Lolipop. Here is the code of a clean project.
package com.mygdx.game;
import com.badlogic.gdx.Application;
import com.badlogic.gdx.Audio;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.ScreenAdapter;
import com.badlogic.gdx.assets.AssetManager;
import com.badlogic.gdx.audio.Sound;
public class MyGdxGame extends ScreenAdapter {
private AssetManager assetManager;
#Override
public void show() {
super.show();
assetManager = new AssetManager();
assetManager.load("sound/jump.mp3", Sound.class);
}
Sound jump;
boolean isLoaded;
#Override
public void render(float delta) {
super.render(delta);
if(isLoaded) return;
assetManager.update();
if(assetManager.isLoaded("sound/jump.mp3", Sound.class)) {
assetManager.finishLoading();
jump = assetManager.get("sound/jump.mp3", Sound.class);
isLoaded = true;
System.err.println("LOADED");
jump.play();
}
}
}
In LOGCAT I'm getting "soundpool sample 1 not ready" error.
Any ideas?
NOTE: The sound is playing as normal if I give it a little time (If I don't press "play" right away).
The question is why does Libgdx thinks that the sound is loaded into memory even if its not.
Have you tried using .ogg instead?
On my libgdx projects i always used .ogg, since its license -free and well, it never gave me issues!
You should also be careful with the different Sound imports. I remember that you can sometimes import directly .ogg .mp3 classes from libgdx and that causes issues.
Also, i think the problem is that, even if the audio file was loaded, the assetmanager is still loading other resources.. so its busy doing another task.
I would either :
a) Play that sound without the assetmanager, since its just for the loading, right?
b) (This needs to be checked) But Maybe use a different assetmanager for that audio? Unsure how much resource would it waste by having 2 assetmanagers..
But, i would try that. Change to .ogg first, be sure the audio starts at exactly 0:00 and update to the last libgdx version.
I'm experiencing the same issue. I am using libgdx version 1.9.2. So far, I tried:
changing mp3 to ogg
using different asset manager for sounds
and it didn't help.
I replaced Sound object with Music object and it did help. But I'm not sure if this is the right approach, because I have a lot of short sounds in my app.
I know this is an old thread but I just ran into this same problem and I solved it like this..
private Sound sound;
private float soundVolume;
public void playSound(String path, float volume) {
sound = assetManager.get(path, Sound.class);
soundVolume = volume;
}
#Override
public void render () {
super.render();
// Because of some weird Android bug
if (sound != null) {
sound.play(soundVolume);
sound = null;
}
}
This is in my main game class and I can call the playSound() method from any other class.
It's probably caused by Gdx.audio.newSound() method is loading the sound by asynchronously instead asserting sound loading process to processor. I solved this by adding a "delay" to the playing sound process only for the first playing. That solved my problem.
private static void soundBugFixer(Sound sfx, float volume)
{
Timer x = new Timer();
x.scheduleTask(new Timer.Task() {
#Override
public void run() {
sfx.play(volume);
}
}, 0.1f );
}
public static void remove(float volume) {
if(sfxRemove == null)
{
sfxRemove = Gdx.audio.newSound(Gdx.files.internal("sfx/sfx_remove.wav"));
soundBugFixer(sfxRemove, volume);
}
else
{
sfxRemove.play(volume);
}
}

How do I use minim library in a java application to detect the beat of an audio source?

Hi everyone!
I am totally new to audio programming and would like to build a Java FX application that interact with audio from my microphone or line out.
I searched google for libraries and found minim which seems pretty popular. It is written for processing but you are able to use it in Java as well. The problem is that I did not find that good documentation about how to do this. (The reason that I do not want to use processing is that I want to build a pretty advance gui, and I think it is easier to do in JavaFX).
As a first step I am trying to build a library that reacts on every beat in a song. My code looks like this:
public class Main extends Application {
/* Used to trick minim constructor (needs an object with those methods) */
class MinimInput {
String sketchPath( String fileName ) {
return "";
}
InputStream createInput(String fileName) {
return new InputStream() {
#Override
public int read() throws IOException {
return 0;
}
};
};
}
#Override
public void start(Stage stage) throws Exception {
...
//Some gui logic here!
...
stage.setScene(scene);
stage.show();
/* Beat detect thread */
Thread th = new Thread(new Runnable() {
#Override
public void run() {
Minim minim = new Minim(new MinimInput());
AudioInput input = minim.getLineIn(Minim.STEREO, 1024); //Tried differen values here
BeatDetect beatDetect = new BeatDetect();
beatDetect.setSensitivity(1000); //Tried different values here
int i=0;
while (true) {
beatDetect.detect(input.mix);
if(beatDetect.isHat()) {
System.out.print("HAT");
}
if(beatDetect.isSnare()) {
System.out.print("SNARE");
}
if (beatDetect.isKick()) {
System.out.print("KICK");
}
}
}
});
th.start();
}
}
I suspect that it could be something with the while(true)-loop and that my soundbuffer gets to small, but I have no idea how I should do this. Can anyone point me in the right direction?
I would also be very thankfull for good resources about audio visualisation programming in general and more specific information on how to do it in java and minim (or tips and examples on how to do this with other libaries if they are easier to use). This is a completely new ground for me, help me break it! :)
I found a solution. Providing BeatDetect with timeSize and sampleRate on init did the trick:
timeSize: the size of the buffer
sampleRate: the sample rate of the samples in the buffer
So... this is what I got:
BeatDetect beatDetect = new BeatDetect(1024, 44100.0f);
1024 is the same as you specify when you get the AudioInput from mime. The sample rate could be found using debug and look at the input value under:
input > stream > format > sampleRate

trying to put a play audio method in my ActionListener

I am trying to put the play method within my Audioapp class inside my ActionListener, I tried putting it in but got errors.
I have read the javadoc on ActionListener but could not find it
This is my audio:
public class Audioapp extends JApplet // find out how to implement play method into action listener?
{
public class Sound // Holds one audio file
{
private AudioClip song; // Sound player
private URL songPath; // Sound path
Sound(String filename)
{
try
{
songPath = new URL(getCodeBase(),"G:\\Uni\\Programming\\Rolling assignements\\Week0\\Programming week21"); // This is the place were im getting error
song = Applet.newAudioClip(songPath); // Load the Sound
}
catch(Exception e){e.printStackTrace();}
}
public void playSound()
{
song.play(); // Play
}
}
}
And this is my actionListener:
class PlayStoHandler implements ActionListener {
public void actionPerformed(ActionEvent event) {
String computerRand = sps.computerChoice();
txtComputerRand.setText(computerRand);
String result = sps.play(Sps.ROCK);
txtResult.setText(result);
scis.setVisible(false);
open.setVisible(false);
stone.setVisible(true);
pap.setVisible(false);
win.setVisible(false);
none.setVisible(false);
lose.setVisible(false);
if (result == "User Wins"){
win.setVisible(true);
song.play(); // here i tried putting the song.play in this if section, the error I got was "song cannot be resolved"
}
else if (result == "Draw"){
none.setVisible(true);
}
else {
lose.setVisible(true);
}
}
I'm a beginner so it's most probably a very stupid basic error
Any help would be appreciated
songPath = new URL(getCodeBase(),"G:\\Uni\\Programming\\Rolling assignements\\Week0\\Programming week21");
The URL constructor expects the second string to represent a relative URL, whereas you have put a file path. URLs always have forward slashes, and a file: based URL there would make little sense (the WAV is hosted on your site, not the HD of the end user).
If the applet is being loaded by HTML at the root of the site with no codebase declared in the HTML, and the wav is called moo.wav and is located in a sub-directory named Week0/Programming week21 the correct path would be:
songPath = new URL(getCodeBase(),"Week0/Programming week21/moo.wav");
But to make things a lot simpler, at least for the moment, put the HTML, the applet and the clip in the same directory and use:
songPath = new URL(getCodeBase(),"moo.wav");
song is private. You created a method to play the sound so use it.
Get the instance of your Audioapp and run the playSound() method.

Categories