Video streaming on Android app with motion on Raspberry Pi - java

I am trying to view a live streaming by motion on my Raspberry Pi through an Android App written with Android Studio...I have compound this code using mplayer:
public class MainActivity extends ActionBarActivity implements SurfaceHolder.Callback, MediaPlayer.OnPreparedListener {
private MediaPlayer mediaPlayer;
private SurfaceHolder vidHolder;
private SurfaceView vidSurface;
String vidAddress = "http://www.example.com/";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
vidSurface = (SurfaceView) findViewById(R.id.surfView);
vidHolder = vidSurface.getHolder();
vidHolder.addCallback(this);
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
try {
mediaPlayer = new MediaPlayer();
mediaPlayer.setDisplay(vidHolder);
mediaPlayer.setDataSource(vidAddress);
mediaPlayer.prepare();
mediaPlayer.setOnPreparedListener(this);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
}
catch(Exception e){
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
#Override
public void onPrepared(MediaPlayer mp) {
mediaPlayer.start();
}
}
But it does not work. If I put an url of a streaming video (not live) for example: www.something.com/vid.mp4 it works. (Yes, I have added internet permission on manifest). Anyone could help me?
Thanks!

I noticed you are inserting a web address without a file at the end - that might be your cause. Motion uses the file stream.mjpg, so the local address by default would be http://hostip:8081/stream.mjpg
Source: http://www.lavrsen.dk/foswiki/bin/view/Motion/MotionGuideBasicFeatures#Webcam_Server

Related

Music player with Seekbar (Android Studio)

I was working in a very simple music player with a seek bar. But I got a problem with playing music,it doesn't work correctly every second - it backwards a while, then remain again like it's a buggy.
I know why but I can't solve it.
When the progress bar moves forward, the music recalibrates and vice versa, when the music moves forward, the progress bar recalibrates.
It's probably because of that that every time it goes back.
But I tried several things and still have the same problem.
Another problem is that when the music is paused, the progress bar goes in the opposite direction until it reaches zero. It doesn't stay where it was before the break.
The full code :
public class MainActivity extends AppCompatActivity {
private MediaPlayer mediaPlayer;
private SeekBar seekBar;
private boolean bool = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.seekBar = (SeekBar) findViewById(R.id.sound_bar);
this.mediaPlayer = MediaPlayer.create(getApplicationContext(), R.raw.music);
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
seekBar.setProgress(mediaPlayer.getCurrentPosition() * seekBar.getMax() / mediaPlayer.getDuration());
}
}, 500, 500);
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
mediaPlayer.seekTo(seekBar.getProgress() * mediaPlayer.getDuration() / seekBar.getMax());
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
public void playSound(View view) {
Button button = (Button) view;
if(bool) {
mediaPlayer.pause();
bool = false;
button.setText("Jouer le son");
} else {
mediaPlayer.start();
bool = true;
button.setText("Mettre en pause");
}
}
#Override
protected void onPause() {
super.onPause();
mediaPlayer.pause();
}
#Override
protected void onStart() {
super.onStart();
if(bool) {
mediaPlayer.start();
}
}
}
Maybe use another thread to control the seekbar would help.
Take a look at this

How to show what's camera seeing in fragment?

The application purpose is to basically compare what's camera seeing vs an image from the gallery. I don't know which control gives you access to the camera without opening the default system app.
I know this app will be useless on split-screen phones (camera on one side and gallery in the other) but is intended to be used in phones without this Nougat functionality (marshmallow or lollipop).
I've seen some apps that display camera like Barcode readers and some quick photo editors.
You can use Camera api. You will need to create your own SurfaceView to display preview of what camera is seeing. There are a lot of tutorial on internet for this.
public class ImageSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
private Camera camera;
private SurfaceHolder surfaceHolder;
public ImageSurfaceView(Context context, Camera camera) {
super(context);
this.camera = camera;
this.surfaceHolder = getHolder();
this.surfaceHolder.addCallback(this);
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
try {
this.camera.setPreviewDisplay(holder);
this.camera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
this.camera.stopPreview();
this.camera.release();
}
}
public class MainActivity extends Activity implements SensorEventListener {
private Camera mCamera;
private ImageSurfaceView cameraView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
protected void onResume(){
super.onResume();
mCamera = getCameraInstance();
mCamera.setDisplayOrientation(90);
cameraView = new ImageSurfaceView(this, mCamera);
mainView.addView(cameraView);
mainView.bringChildToFront(buttonView);
senSensorManager.registerListener(this, senRotation, SensorManager.SENSOR_DELAY_GAME);
}
/** A safe way to get an instance of the Camera object. */
public Camera getCameraInstance(){
Camera c = null;
try{
c = Camera.open(); // attempt to get a Camera instance
Camera.Parameters parameters = c.getParameters();
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
c.setParameters(parameters);
}
catch (Exception e){
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}
}

Fragment and BroadcastReceiver freeze app after some seconds

Here is full code of the app which freezes (UI) after some seconds of work.
Is something dangerous here?
Thank you!
public class FragmentOne extends Fragment {
private Context _context;
private View view;
private BroadcastReceiver broadcastReceiver;
public FragmentOne() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_fragment_one, container, false);
setup();
return view;
}
#Override
public void onAttach(Context context)
{
super.onAttach(context);
_context = context;
}
private void setup()
{
broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent i)
{
try
{
DLocation dLocation = (DLocation) i.getExtras().get("coordinates");
if (dLocation != null) {
Log.d("Первый фрагмент", "Применение параметров шир. сообщения к контролам окна");
TextView textLon = (TextView)view.findViewById(R.id.textLon);
textLon.setText(dLocation.Longitude);
TextView textLat = (TextView)view.findViewById(R.id.textLat);
textLat.setText(dLocation.Latitude);
TextView textTime = (TextView)view.findViewById(R.id.textTime);
textTime.setText(dLocation.TimeOfRequest);
TextView textErrors = (TextView)view.findViewById(R.id.textErrors);
textErrors.setText(dLocation.Errors);
}
}
catch (Exception ex)
{
Toast.makeText(getActivity(), ex.getMessage(), Toast.LENGTH_LONG).show();
}
}
};
_context.registerReceiver(broadcastReceiver, new IntentFilter("location_update"));
}
#Override
public void onResume() {
super.onResume();
}
#Override
public void onPause() {
super.onPause();
}
#Override
public void onDestroy() {
super.onDestroy();
if (broadcastReceiver != null) {
_context.unregisterReceiver(broadcastReceiver);
}
}
}
Root Cause
I think you are using a 3rd party library to detect location. The library is receiving the GPS coordinates at a very high rate. These coordinates are then received by your broadcast receiver. Your broadcast receiver is doing it's work on the UI thread. The reason why your app freezes is because the UI thread is doing work at very high rate.
Solution
The solution to your problem lies in Bound Service. You can find code examples in android developer docs Bound Services.
For use cases like a music player, where media is played in a background thread but duration of played music is shown on the UI, bound service can be useful. I hope this sets you in the right direction.

How to animate TextureView?

I am trying to fade in a TextureView but for some reason its not animating. It just simply pops in the video, no fade at all and i dont really know why that is because after some research i have found that TextureView can be animated normally.
Here is my code, i hope you guys can give me a pointer in the right direction.
PS, i have left out all irrelevant code that does not concern itself with the textureview and the animation.
public class MainActivity extends AppCompatActivity implements MediaPlayer.OnPreparedListener, MediaPlayer.OnCompletionListener
{
private static final String TAG = MainActivity.class.getSimpleName();
private MediaPlayer mediaPlayer1;
private ArrayList<Uri> videoUris = new ArrayList<>();
private int current_video_index = 0;
private TextureView textureView;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textureView = (TextureView) findViewById(R.id.textureView);
mediaPlayer1 = new MediaPlayer();
mediaPlayer1.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer1.setOnPreparedListener(this);
mediaPlayer1.setOnCompletionListener(this);
initVideoUris();
initNewVideo();
}
private void startVideo(final Uri uri)
{
textureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener()
{
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height)
{
try {
mediaPlayer1.setDataSource(MainActivity.this, uri);
mediaPlayer1.setSurface(new Surface(surface));
mediaPlayer1.setOnCompletionListener(MainActivity.this);
mediaPlayer1.setOnPreparedListener(MainActivity.this);
mediaPlayer1.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer1.prepareAsync();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height)
{
}
#Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface)
{
return false;
}
#Override
public void onSurfaceTextureUpdated(SurfaceTexture surface)
{
}
});
}
#Override
public void onPrepared(MediaPlayer mp)
{
mp.start();
fadeInView(textureView);
}
#Override
public void onCompletion(MediaPlayer mp)
{
if (!moreVideosAvailable())
{
finish();
}
}
private boolean moreVideosAvailable()
{
return current_video_index < videoUris.size();
}
private void fadeInView(View view)
{
view.setAlpha(0f);
view.setVisibility(View.VISIBLE);
view.animate().alpha(1f).setDuration(2000).setListener(null).start();
}
}
I solved it by making a videoPlayerFragment that uses TextureView as the surface for displaying the video. Then simply animate the whole fragment instead of the textureView.

Can't get media player to play mp3

Can anyone tell me why this code doesn't work? It compiles but when I click on the button nothing plays and then it crashes. I'm a noob =[
public class MainActivity extends ActionBarActivity {
private MediaPlayer newTune;
public void playB(View paramView) throws IOException {
newTune = MediaPlayer.create(this, R.raw.b);
if (newTune.isPlaying()) {
// newTune.stop();
} else {
newTune.prepare();
newTune.start();
}
}
There are a couple of problems I can see.
1.) You don't need to call prepare(), as create() has already taken care of this for you.
2.) newTune.isPlaying() is always going to be false, as you've just created a new MediaPlayer.
From the docs:
http://developer.android.com/reference/android/media/MediaPlayer.html
MediaPlayer.onCreate()...
Convenience method to create a MediaPlayer for a given resource id. On
success, prepare() will already have been called and must not be
called again.
Try something like this:
public class MainActivity extends ActionBarActivity {
private MediaPlayer newTune;
public void play() {
newTune = MediaPlayer.create(this, R.raw.b);
newTune.start();
}
}
Here's a simple example of a better way of handling the whole thing:
public class MainActivity extends Activity {
private MediaPlayer mMediaPlayer;
private boolean mIsPrepared;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mMediaPlayer = MediaPlayer.create(this, R.raw.raw1);
mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mIsPrepared = true;
}
});
Button button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
playOrPause();
}
});
}
public void playOrPause() {
if (mMediaPlayer == null || !mIsPrepared) {
return;
}
if (!mMediaPlayer.isPlaying()) {
mMediaPlayer.start();
} else {
mMediaPlayer.pause();
}
}
}

Categories