Страница 1 из 2
Видео из res/raw
Добавлено: 21 июл 2013, 23:18
=bor=
MediaPlayer + SurfaceView, видеофайл video.mp4 в папке res/raw.
Код: Выделить всё
mMediaPlayer = MediaPlayer.create(this, R.raw.video);
mMediaPlayer.setDataSource(path);
mMediaPlayer.setDisplay(holder);
Вот с этим path замучился.
Если так:
path = Uri.parse("android.resource://"+getPackageName()+"/"+R.raw.video).toString();
то в логе:
Код: Выделить всё
07-21 20:15:15.622: D/MediaPlayerVideo(7907): surfaceCreated called
07-21 20:15:16.772: E/MediaPlayer(7907): attachNewPlayer called in state 8
07-21 20:15:16.825: E/MediaPlayerVideo(7907): error: null
07-21 20:15:16.825: E/MediaPlayerVideo(7907): java.lang.IllegalStateException
07-21 20:15:16.825: E/MediaPlayerVideo(7907): at android.media.MediaPlayer._setDataSource(Native Method)
07-21 20:15:16.825: E/MediaPlayerVideo(7907): at android.media.MediaPlayer.setDataSource(MediaPlayer.java:958)
07-21 20:15:16.825: E/MediaPlayerVideo(7907): at android.media.MediaPlayer.setDataSource(MediaPlayer.java:918)
07-21 20:15:16.825: E/MediaPlayerVideo(7907): at com.example.mediaplayer_video2.Mediaplayer_video2.playVideo(Mediaplayer_video2.java:78)
07-21 20:15:16.825: E/MediaPlayerVideo(7907): at com.example.mediaplayer_video2.Mediaplayer_video2.surfaceCreated(Mediaplayer_video2.java:137)
Есть идеи, как правильно задать path?
Re: Видео из res/raw
Добавлено: 21 июл 2013, 23:33
=bor=
Тут
Play Video From Raw Folder есть решение с помощью VideoView, но мне нужно SurfaceView.
Тут
How to play videos in android from assets folder or raw folder? нет решения, но забугорный товарищ
Khajan предлагает алгоритм, но я с этим совершенно не знаком, да и неизвестно, рабочий ли алгоритм:
a- Use the MediaPlayer API and the sample code.
b- put the media file in raw folder
c- get the file descriptor to the file
d- mediaplayer.setDataSource(fd,offset,length); - its a three argument constructor
e- then when onPreared , mediaplayer.start();
Кто-нибудь сталкивался с получением fd из res/raw?
Re: Видео из res/raw
Добавлено: 22 июл 2013, 09:33
=bor=
Утро доброе!
Попробовал предложенное тут -
FileNotFoundException with MediaPlayer.create() reading from /res/raw - решение с получением дескриптора файла - падает с таким логом:
07-22 06:30:40.212: D/MediaPlayerVideo(19284): surfaceCreated called
07-22 06:30:41.312: D/MediaPlayerVideo(19284): surfaceChanged called
07-22 06:30:41.342: I/Choreographer(19284): Skipped 166 frames! The application may be doing too much work on its main thread.
07-22 06:30:41.592: D/gralloc_goldfish(19284): Emulator without GPU emulation detected.
07-22 06:30:42.464: V/MediaPlayerVideo(19284): onVideoSizeChanged called
07-22 06:30:42.464: D/MediaPlayerVideo(19284): onPrepared called
07-22 06:30:42.492: V/MediaPlayerVideo(19284): startVideoPlayback
07-22 06:30:42.492: D/AndroidRuntime(19284): Shutting down VM
07-22 06:30:42.502: W/dalvikvm(19284): threadid=1: thread exiting with uncaught exception (group=0x40a13300)
07-22 06:30:42.612: E/AndroidRuntime(19284): FATAL EXCEPTION: main
07-22 06:30:42.612: E/AndroidRuntime(19284): java.lang.NullPointerException
07-22 06:30:42.612: E/AndroidRuntime(19284): at com.example.mediaplayer_video2.Mediaplayer_video2.startVideoPlayback(Mediaplayer_video2.java:179)
07-22 06:30:42.612: E/AndroidRuntime(19284): at com.example.mediaplayer_video2.Mediaplayer_video2.onPrepared(Mediaplayer_video2.java:126)
Код: Выделить всё
private void startVideoPlayback() {
Log.v(TAG, "startVideoPlayback");
holder.setFixedSize(mVideoWidth, mVideoHeight);
mMediaPlayer.start(); ------------------------- строка 179
Код: Выделить всё
public void onPrepared(MediaPlayer mediaplayer) {
Log.d(TAG, "onPrepared called");
mIsVideoReadyToBePlayed = true;
if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) {
startVideoPlayback(); ----------------------------строка 126
Есть мысли?
Re: Видео из res/raw
Добавлено: 22 июл 2013, 12:41
Finch
у тебя плеер = null
как ты его инициализируешь?
правильно вообще-то использовать локальный плеер который приходит в onPrepared.
Re: Видео из res/raw
Добавлено: 22 июл 2013, 12:56
=bor=
Finch писал(а):у тебя плеер = null
как ты его инициализируешь?
Вот код:
Код: Выделить всё
/*
* version #02
*
*/
package com.example.mediaplayer_video2;
import android.app.Activity;
import android.content.res.AssetFileDescriptor;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnBufferingUpdateListener;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.media.MediaPlayer.OnVideoSizeChangedListener;
// import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
// import android.widget.Toast;
public class Mediaplayer_video2 extends Activity implements
OnBufferingUpdateListener, OnCompletionListener,
OnPreparedListener, OnVideoSizeChangedListener, SurfaceHolder.Callback {
private static final String TAG = "MediaPlayerVideo";
private int mVideoWidth;
private int mVideoHeight;
private MediaPlayer mMediaPlayer;
private SurfaceView mPreview;
private SurfaceHolder holder;
private String path;
// private Bundle extras;
// private static final String MEDIA = "media";
private boolean mIsVideoSizeKnown = false;
private boolean mIsVideoReadyToBePlayed = false;
/**
*
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.mediaplayer_2);
mPreview = (SurfaceView) findViewById(R.id.surface);
holder = mPreview.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
// extras = getIntent().getExtras();
}
//private void playVideo(Integer Media) {
private void playVideo() {
doCleanUp();
try {
// path = "sdcard/scheen.mp4";
// path = Uri.parse("android.resource://"+getPackageName()+"/"+R.raw.video).toString();
// path = "sdcard/lesson01.mp4";
// if (path = "") {
// Tell the user to provide a media file URL.
// Toast
// .makeText(
// Mediaplayer_video2.this,
// "Please edit Mediaplayer_Video Activity, "
// + "and set the path variable to your media file path."
// + " Your media file must be stored on sdcard.",
// Toast.LENGTH_LONG).show();
// }
// Create a new media player and set the listeners
// mMediaPlayer = MediaPlayer.create(this, R.raw.video);
// mMediaPlayer = new MediaPlayer();
MediaPlayer mMediaPlayer = new MediaPlayer();
AssetFileDescriptor afd = getResources().openRawResourceFd(R.raw.video);
mMediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
// mMediaPlayer.setDataSource(path);
mMediaPlayer.setDisplay(holder);
mMediaPlayer.prepare();
mMediaPlayer.setOnBufferingUpdateListener(this);
mMediaPlayer.setOnCompletionListener(this);
mMediaPlayer.setOnPreparedListener(this);
mMediaPlayer.setOnVideoSizeChangedListener(this);
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
} catch (Exception e) {
Log.e(TAG, "error: " + e.getMessage(), e);
}
}
public void onBufferingUpdate(MediaPlayer arg0, int percent) {
Log.d(TAG, "onBufferingUpdate percent:" + percent);
}
public void onCompletion(MediaPlayer arg0) {
Log.d(TAG, "onCompletion called");
}
public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
Log.v(TAG, "onVideoSizeChanged called");
if (width == 0 || height == 0) {
Log.e(TAG, "invalid video width(" + width + ") or height(" + height + ")");
return;
}
mIsVideoSizeKnown = true;
mVideoWidth = width;
mVideoHeight = height;
if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) {
startVideoPlayback();
}
}
public void onPrepared(MediaPlayer mediaplayer) {
Log.d(TAG, "onPrepared called");
mIsVideoReadyToBePlayed = true;
if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) {
startVideoPlayback();
}
}
public void surfaceChanged(SurfaceHolder surfaceholder, int i, int j, int k) {
Log.d(TAG, "surfaceChanged called");
}
public void surfaceDestroyed(SurfaceHolder surfaceholder) {
Log.d(TAG, "surfaceDestroyed called");
}
public void surfaceCreated(SurfaceHolder holder) {
Log.d(TAG, "surfaceCreated called");
// playVideo(extras.getInt(MEDIA));
playVideo();
}
@Override
protected void onPause() {
super.onPause();
releaseMediaPlayer();
doCleanUp();
}
@Override
protected void onDestroy() {
super.onDestroy();
releaseMediaPlayer();
doCleanUp();
}
private void releaseMediaPlayer() {
if (mMediaPlayer != null) {
mMediaPlayer.release();
mMediaPlayer = null;
}
}
private void doCleanUp() {
mVideoWidth = 0;
mVideoHeight = 0;
mIsVideoReadyToBePlayed = false;
mIsVideoSizeKnown = false;
}
private void startVideoPlayback() {
Log.v(TAG, "startVideoPlayback");
holder.setFixedSize(mVideoWidth, mVideoHeight);
mMediaPlayer.start();
}
}
Re: Видео из res/raw
Добавлено: 23 июл 2013, 09:48
=bor=
Мыслей ни у кого нет, обеднел наш форум мыслителями.
Изменил способ инициализации MediaPlayer - теперь через .create(), чтоб не ругался на prepare():
Код: Выделить всё
mMediaPlayer = MediaPlayer.create(this, R.raw.video);
// MediaPlayer mMediaPlayer = new MediaPlayer();
AssetFileDescriptor afd = getResources().openRawResourceFd(R.raw.video);
mMediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
// mMediaPlayer.setDataSource(path);
mMediaPlayer.setDisplay(holder);
// mMediaPlayer.prepare();
Всё-равно падает.
Re: Видео из res/raw
Добавлено: 23 июл 2013, 14:33
Finch
Дружище ну бред же =)
private MediaPlayer mMediaPlayer;
MediaPlayer mMediaPlayer = new MediaPlayer();
ты создаешь глобалку под именем mMediaPlayer и не инициализируешь ее. Плеер у тебя null. Потом создаешь локалку под тем же именем и там есть инициализация но видно твой плеер только в методе playVideo(). Какой смысл в 2-х одинаковых переменных?
Когда в методе startVideoPlayback() обращаешься к плееру mMediaPlayer.start(); который равен null у тебя и вылазит нуллпоинтер.
Выход: смени в методе playVideo() строку MediaPlayer mMediaPlayer = new MediaPlayer(); на mMediaPlayer = new MediaPlayer();
П.С. в общем тебе нужно сделать так чтоб mMediaPlayer везде был синего цвета(если ты кодишь в Эклипс со стандартными настройками подсветки синтаксиса) это если по нубски говорить =)
Re: Видео из res/raw
Добавлено: 23 июл 2013, 20:55
=bor=
Finch писал(а):Дружище ну бред же =)
Не всегда бред - бред, чаще - невнимательность.
Finch писал(а):П.С. в общем тебе нужно сделать так чтоб mMediaPlayer везде был синего цвета(если ты кодишь в Эклипс со стандартными настройками подсветки синтаксиса) это если по нубски говорить =)
Всё синее, но private MediaPlayer mMediaPlayer; оранжевый. Что означает эта подсветка, где почитать?
Finch писал(а):смени в методе playVideo() строку MediaPlayer mMediaPlayer = new MediaPlayer(); на mMediaPlayer = new MediaPlayer();
За изловленный баг спасибо, дружище.
Re: Видео из res/raw
Добавлено: 24 июл 2013, 08:33
Finch
Оранжевый или подчеркнутый жёлтым? Подчеркнутый желтый означает что ты нигде не используешь переменную.
Re: Видео из res/raw
Добавлено: 24 июл 2013, 09:27
=bor=
С жёлтым уже давно разобрался.
Оранжевый:
- orange-2.jpg (58.11 КБ) 12682 просмотра
Re: Видео из res/raw
Добавлено: 24 июл 2013, 09:54
xr0m
Подсветка выделенной переменной по всему коду.
Re: Видео из res/raw
Добавлено: 24 июл 2013, 10:07
=bor=
xr0m писал(а):Подсветка выделенной переменной по всему коду.
А почему ниже оно же синее?
Эта разметка где-то описана? Перерыл всё в Window/Preferences/General/Color и Editors - не нашёл.
Re: Видео из res/raw
Добавлено: 24 июл 2013, 20:43
Finch
Re: Видео из res/raw
Добавлено: 25 июл 2013, 09:46
=bor=
Да, вижу, но что с этим делать? Где-то написано, чем заменить?
По этим ссылям не нашёл, в Гугле тоже пока.
Мин. таргет - 16.
Re: Видео из res/raw
Добавлено: 25 июл 2013, 11:55
=bor=
Кстати, загляните в SDK - там появился Андроид 4.3 (API 18).
Сейчас посмотрю, там тоже deprecated или что-то новое, а то и в АПИ 16 и АПИ 17 в Samples в примере MediaPlayer приведён именно он - holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); (deprecated).
EDIT. Нету.
Там из Media только basicmediarouter.
Re: Видео из res/raw
Добавлено: 25 июл 2013, 18:54
Finch
Из документации, читай и понимай =) Если у тебя апи 16 то в этой строке нет смысла так как value is set automatically when needed
public abstract void setType (int type)
Added in API level 1
This method was deprecated in API level 11.
this is ignored, this value is set automatically when needed.
Re: Видео из res/raw
Добавлено: 25 июл 2013, 19:10
=bor=
Finch писал(а):Если у тебя апи 16 то в этой строке нет смысла так как value is set automatically when needed
То есть, её можно удалить?
Щас попробую...
EDIT. Фурычед!! Красотень.
Спасибо.
Сегодня весь Стэк перелопатил и Гугл, но не нашёл, что это за код инфо:
07-25 16:15:31.943: V/MediaPlayerVideo(4551): startVideoPlayback
07-25 16:15:33.933: W/MediaPlayer(4551): info/warning (900, -38)
07-25 16:15:33.943: I/MediaPlayer(4551): Info (900,-38)
Всё работает, но вот такие недопонятости мешают этому радоваться.
Re: Видео из res/raw
Добавлено: 26 июл 2013, 01:17
Finch
видишь тэги лога?
это warning и тд и тп) забей кароч)
http://developer.android.com/reference/ ... Log.html#w(java.lang.String, java.lang.String)
Re: Видео из res/raw
Добавлено: 26 июл 2013, 07:58
klblk
Офтоп небольшой.
=bor= писал(а):Кстати, загляните в SDK - там появился Андроид 4.3 (API 18).
Еще там появилось Android SDK Build-tools rev 18, причём автоматически галочка там не поставилась, и в списке также осталась 17 версия:
http://gyazo.com/5e4f761641075de9be4d48fa5f4d2ebb
Собственно, кто-нибуть это устанавливал?.. а то я боюсь за проекты свои:)
Re: Видео из res/raw
Добавлено: 26 июл 2013, 09:20
=bor=
Вижу, info - это так, к сведению, беспокоиться не о чём, но что-то же Далвик хочет до меня этим донести?
За ссылочку спасибо, уже читал.
Особенно повеселило там
public static int wtf ().
Правда, это не
What The Fuck?, а
What a Terrible Failure