experimental: inline video player
This commit is contained in:
parent
a4609d054e
commit
9420b9570e
|
@ -13,6 +13,7 @@ import android.graphics.Bitmap;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.Point;
|
import android.graphics.Point;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.media.MediaPlayer;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
@ -36,6 +37,8 @@ import android.view.Display;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
import android.view.SurfaceHolder;
|
||||||
|
import android.view.SurfaceView;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnClickListener;
|
import android.view.View.OnClickListener;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
@ -78,6 +81,7 @@ import org.fox.ttrss.types.ArticleList;
|
||||||
import org.fox.ttrss.types.Feed;
|
import org.fox.ttrss.types.Feed;
|
||||||
import org.fox.ttrss.util.HeadlinesRequest;
|
import org.fox.ttrss.util.HeadlinesRequest;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -126,6 +130,9 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
|
||||||
private View m_topChangedView;
|
private View m_topChangedView;
|
||||||
private View m_amrFooterView;
|
private View m_amrFooterView;
|
||||||
|
|
||||||
|
private MediaPlayer m_mediaPlayer;
|
||||||
|
private SurfaceView m_activeSurface;
|
||||||
|
|
||||||
public ArticleList getSelectedArticles() {
|
public ArticleList getSelectedArticles() {
|
||||||
ArticleList tmp = new ArticleList();
|
ArticleList tmp = new ArticleList();
|
||||||
|
|
||||||
|
@ -708,6 +715,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
|
||||||
public View headlineHeader;
|
public View headlineHeader;
|
||||||
public View topChangedMessage;
|
public View topChangedMessage;
|
||||||
public View flavorImageOverflow;
|
public View flavorImageOverflow;
|
||||||
|
public SurfaceView flavorVideoView;
|
||||||
public int position;
|
public int position;
|
||||||
public boolean flavorImageEmbedded;
|
public boolean flavorImageEmbedded;
|
||||||
}
|
}
|
||||||
|
@ -933,6 +941,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
|
||||||
holder.headlineHeader = v.findViewById(R.id.headline_header);
|
holder.headlineHeader = v.findViewById(R.id.headline_header);
|
||||||
holder.topChangedMessage = v.findViewById(R.id.headlines_row_top_changed);
|
holder.topChangedMessage = v.findViewById(R.id.headlines_row_top_changed);
|
||||||
holder.flavorImageOverflow = v.findViewById(R.id.flavor_image_overflow);
|
holder.flavorImageOverflow = v.findViewById(R.id.flavor_image_overflow);
|
||||||
|
holder.flavorVideoView = (SurfaceView) v.findViewById(R.id.flavor_video);
|
||||||
|
|
||||||
v.setTag(holder);
|
v.setTag(holder);
|
||||||
|
|
||||||
|
@ -1106,6 +1115,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
|
||||||
holder.flavorImageView.setVisibility(View.GONE);
|
holder.flavorImageView.setVisibility(View.GONE);
|
||||||
holder.flavorVideoKindView.setVisibility(View.GONE);
|
holder.flavorVideoKindView.setVisibility(View.GONE);
|
||||||
holder.flavorImageOverflow.setVisibility(View.GONE);
|
holder.flavorImageOverflow.setVisibility(View.GONE);
|
||||||
|
holder.flavorVideoView.setVisibility(View.GONE);
|
||||||
holder.headlineHeader.setBackgroundDrawable(null);
|
holder.headlineHeader.setBackgroundDrawable(null);
|
||||||
|
|
||||||
// this is needed if our flavor image goes behind base listview element
|
// this is needed if our flavor image goes behind base listview element
|
||||||
|
@ -1176,6 +1186,61 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
|
||||||
holder.flavorImageLoadingBar.setVisibility(View.VISIBLE);
|
holder.flavorImageLoadingBar.setVisibility(View.VISIBLE);
|
||||||
holder.flavorImageLoadingBar.setIndeterminate(true);
|
holder.flavorImageLoadingBar.setIndeterminate(true);
|
||||||
|
|
||||||
|
/*if ("video".equals(article.flavorImage.tagName().toLowerCase()) && article.flavorStreamUri != null) {
|
||||||
|
final MediaPlayer mediaPlayer = new MediaPlayer();
|
||||||
|
|
||||||
|
holder.flavorVideoView.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
|
repositionFlavorVideo(holder.flavorVideoView, holder);
|
||||||
|
|
||||||
|
try {
|
||||||
|
mediaPlayer.setDataSource(article.flavorStreamUri);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
final View bar = holder.flavorImageLoadingBar;
|
||||||
|
SurfaceHolder sh = holder.flavorVideoView.getHolder();
|
||||||
|
|
||||||
|
sh.addCallback(new SurfaceHolder.Callback() {
|
||||||
|
@Override
|
||||||
|
public void surfaceCreated(SurfaceHolder holder) {
|
||||||
|
mediaPlayer.setDisplay(holder);
|
||||||
|
try {
|
||||||
|
mediaPlayer.prepareAsync();
|
||||||
|
} catch (IllegalStateException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
|
||||||
|
@Override
|
||||||
|
public void onPrepared(MediaPlayer mp) {
|
||||||
|
|
||||||
|
bar.setVisibility(View.GONE);
|
||||||
|
|
||||||
|
//resizeSurface();
|
||||||
|
mp.setLooping(true);
|
||||||
|
mp.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} else { */
|
||||||
|
|
||||||
holder.flavorImageView.setVisibility(View.VISIBLE);
|
holder.flavorImageView.setVisibility(View.VISIBLE);
|
||||||
holder.flavorImageView.setImageDrawable(null);
|
holder.flavorImageView.setImageDrawable(null);
|
||||||
|
|
||||||
|
@ -1208,7 +1273,9 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
|
||||||
holder.flavorImageView.setVisibility(View.VISIBLE);
|
holder.flavorImageView.setVisibility(View.VISIBLE);
|
||||||
holder.flavorImageOverflow.setVisibility(View.VISIBLE);
|
holder.flavorImageOverflow.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
maybeRepositionFlavorImage(holder.flavorImageView, resource, holder);
|
boolean forceDown = article.flavorImage != null && "video".equals(article.flavorImage.tagName().toLowerCase());
|
||||||
|
|
||||||
|
maybeRepositionFlavorImage(holder.flavorImageView, resource, holder, forceDown);
|
||||||
adjustVideoKindView(holder, article);
|
adjustVideoKindView(holder, article);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -1220,14 +1287,108 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
|
||||||
.into(glideImage);
|
.into(glideImage);
|
||||||
}
|
}
|
||||||
|
|
||||||
holder.flavorImageView.setOnClickListener(new OnClickListener() {
|
if (m_prefs.getBoolean("inline_video_player", false) && article.flavorImage != null &&
|
||||||
@Override
|
"video".equals(article.flavorImage.tagName().toLowerCase()) && article.flavorStreamUri != null) {
|
||||||
public void onClick(View view) {
|
|
||||||
|
|
||||||
|
holder.flavorImageView.setOnLongClickListener(new View.OnLongClickListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onLongClick(View v) {
|
||||||
|
|
||||||
|
openGalleryForType(article, holder, null);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
holder.flavorImageView.setOnClickListener(new OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
|
||||||
|
if (m_mediaPlayer != null) {
|
||||||
|
m_mediaPlayer.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_activeSurface != null) {
|
||||||
|
m_activeSurface.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_mediaPlayer = new MediaPlayer();
|
||||||
|
|
||||||
|
try {
|
||||||
|
m_mediaPlayer.setDataSource(article.flavorStreamUri);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
SurfaceHolder sh = holder.flavorVideoView.getHolder();
|
||||||
|
|
||||||
|
|
||||||
|
holder.flavorVideoView.setVisibility(View.VISIBLE);
|
||||||
|
final ProgressBar bar = holder.flavorImageLoadingBar;
|
||||||
|
|
||||||
|
bar.setIndeterminate(true);
|
||||||
|
bar.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
|
holder.flavorVideoView.setOnClickListener(new OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
if (m_mediaPlayer.isPlaying())
|
||||||
|
m_mediaPlayer.pause();
|
||||||
|
else
|
||||||
|
m_mediaPlayer.start();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
m_activeSurface = holder.flavorVideoView;
|
||||||
|
|
||||||
|
sh.addCallback(new SurfaceHolder.Callback() {
|
||||||
|
@Override
|
||||||
|
public void surfaceCreated(SurfaceHolder holder) {
|
||||||
|
m_mediaPlayer.setDisplay(holder);
|
||||||
|
|
||||||
|
try {
|
||||||
|
m_mediaPlayer.prepareAsync();
|
||||||
|
} catch (IllegalStateException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
m_mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
|
||||||
|
@Override
|
||||||
|
public void onPrepared(MediaPlayer mp) {
|
||||||
|
|
||||||
|
bar.setVisibility(View.GONE);
|
||||||
|
|
||||||
|
//resizeSurface();
|
||||||
|
mp.setLooping(true);
|
||||||
|
mp.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
|
||||||
|
bar.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||||
|
bar.setVisibility(View.GONE);
|
||||||
|
|
||||||
|
m_mediaPlayer.release();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
} else {
|
||||||
|
holder.flavorImageView.setOnClickListener(new OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
openGalleryForType(article, holder, null);
|
openGalleryForType(article, holder, null);
|
||||||
|
}
|
||||||
}
|
});
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String articleAuthor = article.author != null ? article.author : "";
|
String articleAuthor = article.author != null ? article.author : "";
|
||||||
|
@ -1390,7 +1551,15 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
|
||||||
return px;
|
return px;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void maybeRepositionFlavorImage(View view, GlideDrawable resource, HeadlineViewHolder holder) {
|
private void repositionFlavorVideo(View view, HeadlineViewHolder holder) {
|
||||||
|
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) view.getLayoutParams();
|
||||||
|
|
||||||
|
lp.addRule(RelativeLayout.BELOW, R.id.headline_header);
|
||||||
|
|
||||||
|
view.setLayoutParams(lp);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void maybeRepositionFlavorImage(View view, GlideDrawable resource, HeadlineViewHolder holder, boolean forceDown) {
|
||||||
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) view.getLayoutParams();
|
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) view.getLayoutParams();
|
||||||
|
|
||||||
int w = resource.getIntrinsicWidth();
|
int w = resource.getIntrinsicWidth();
|
||||||
|
@ -1399,7 +1568,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
|
||||||
|
|
||||||
//Log.d(TAG, "XYR: " + pxToDp(w) + " " + pxToDp(h) + " " + r);
|
//Log.d(TAG, "XYR: " + pxToDp(w) + " " + pxToDp(h) + " " + r);
|
||||||
|
|
||||||
if (h < m_minimumHeightToEmbed || r >= 1.2) {
|
if (forceDown || h < m_minimumHeightToEmbed || r >= 1.2) {
|
||||||
|
|
||||||
lp.addRule(RelativeLayout.BELOW, R.id.headline_header);
|
lp.addRule(RelativeLayout.BELOW, R.id.headline_header);
|
||||||
|
|
||||||
|
@ -1567,6 +1736,22 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onScrollStateChanged(AbsListView view, int scrollState) {
|
public void onScrollStateChanged(AbsListView view, int scrollState) {
|
||||||
|
if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_FLING || scrollState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
|
||||||
|
|
||||||
|
/*if (m_activeSurface != null) {
|
||||||
|
m_activeSurface.setVisibility(View.GONE);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (m_mediaPlayer != null && m_mediaPlayer.isPlaying()) {
|
||||||
|
m_mediaPlayer.pause();
|
||||||
|
}
|
||||||
|
} catch (IllegalStateException e) {
|
||||||
|
// i guess it was already released, oh well
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (scrollState == SCROLL_STATE_IDLE && m_prefs.getBoolean("headlines_mark_read_scroll", false)) {
|
if (scrollState == SCROLL_STATE_IDLE && m_prefs.getBoolean("headlines_mark_read_scroll", false)) {
|
||||||
if (!m_readArticles.isEmpty()) {
|
if (!m_readArticles.isEmpty()) {
|
||||||
m_activity.toggleArticlesUnread(m_readArticles);
|
m_activity.toggleArticlesUnread(m_readArticles);
|
||||||
|
|
|
@ -159,7 +159,7 @@ public class MasterActivity extends OnlineActivity implements HeadlinesEventList
|
||||||
HeadlinesFragment hf = new HeadlinesFragment();
|
HeadlinesFragment hf = new HeadlinesFragment();
|
||||||
|
|
||||||
if (BuildConfig.DEBUG) {
|
if (BuildConfig.DEBUG) {
|
||||||
hf.initialize(new Feed(-4, "All articles", false));
|
hf.initialize(new Feed(-1, "Starred articles", false));
|
||||||
} else {
|
} else {
|
||||||
hf.initialize(new Feed(-3, getString(R.string.fresh_articles), false));
|
hf.initialize(new Feed(-3, getString(R.string.fresh_articles), false));
|
||||||
}
|
}
|
||||||
|
|
|
@ -261,7 +261,7 @@ public class VideoPlayerActivity extends CommonActivity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void surfaceDestroyed(SurfaceHolder holder) {
|
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||||
//
|
mediaPlayer.release();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,22 @@
|
||||||
android:src="@drawable/drawer_header"
|
android:src="@drawable/drawer_header"
|
||||||
android:visibility="visible" />
|
android:visibility="visible" />
|
||||||
|
|
||||||
|
<SurfaceView
|
||||||
|
android:id="@+id/flavor_video"
|
||||||
|
android:foreground="@drawable/ripple"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:adjustViewBounds="true"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
android:cropToPadding="true"
|
||||||
|
android:src="@drawable/drawer_header"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:layout_alignBottom="@+id/flavor_image"
|
||||||
|
android:layout_alignTop="@+id/flavor_image" />
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:id="@+id/headline_header"
|
android:id="@+id/headline_header"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
|
|
|
@ -57,6 +57,22 @@
|
||||||
android:src="@drawable/drawer_header"
|
android:src="@drawable/drawer_header"
|
||||||
android:visibility="visible" />
|
android:visibility="visible" />
|
||||||
|
|
||||||
|
<SurfaceView
|
||||||
|
android:id="@+id/flavor_video"
|
||||||
|
android:foreground="@drawable/ripple"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:adjustViewBounds="true"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
android:cropToPadding="true"
|
||||||
|
android:src="@drawable/drawer_header"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:layout_alignBottom="@+id/flavor_image"
|
||||||
|
android:layout_alignTop="@+id/flavor_image" />
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:id="@+id/headline_header"
|
android:id="@+id/headline_header"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
|
|
|
@ -134,6 +134,12 @@
|
||||||
android:key="open_fresh_on_startup"
|
android:key="open_fresh_on_startup"
|
||||||
android:title="@string/prefs_open_fresh_on_startup" />
|
android:title="@string/prefs_open_fresh_on_startup" />
|
||||||
|
|
||||||
|
<org.fox.ttrss.util.LessBrokenSwitchPreference
|
||||||
|
android:defaultValue="false"
|
||||||
|
android:key="inline_video_player"
|
||||||
|
android:summary="Experimental: play videos inside headlines list. Long tap to open separate player"
|
||||||
|
android:title="Inline video player" />
|
||||||
|
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
<PreferenceCategory android:title="@string/reading" >
|
<PreferenceCategory android:title="@string/reading" >
|
||||||
<org.fox.ttrss.util.FontSizeDialogPreference
|
<org.fox.ttrss.util.FontSizeDialogPreference
|
||||||
|
@ -218,6 +224,7 @@
|
||||||
android:summary="@string/prefs_widget_show_fresh_summary" />
|
android:summary="@string/prefs_widget_show_fresh_summary" />
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
<PreferenceCategory android:title="@string/debugging" >
|
<PreferenceCategory android:title="@string/debugging" >
|
||||||
|
|
||||||
<org.fox.ttrss.util.LessBrokenSwitchPreference
|
<org.fox.ttrss.util.LessBrokenSwitchPreference
|
||||||
android:defaultValue="true"
|
android:defaultValue="true"
|
||||||
android:key="webview_hardware_accel"
|
android:key="webview_hardware_accel"
|
||||||
|
|
Loading…
Reference in New Issue
Block a user