基本架构
1、使用SurfaceView在UI层面展示视频 2、通过JNI调用C代码控制视频的播放、停止
基本功能
1、从服务器获取正则直播的主播的列表信息 2、进入直播界面 3、可获取的主播信息
Activity_列表
public class MainActivity extends Activity { public static final String SERVER_URL = "api.95xiu.com";//"tapi.95xiu.com" public static final String RQ_LIVE = "/show/anchor_list_v3.php"; private List<LiveBean> mList; private GridView gridView; private MyBaseAdapter adapter; private DisplayImageOptions options; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE);//取消标题栏 ImageLoader.getInstance().init(new ImageLoaderConfiguration.Builder(this).build()); options = new DisplayImageOptions.Builder().cacheInMemory(true).cacheOnDisk(true)//将图片缓存到内存和硬盘中 .showImageOnLoading(R.drawable.live_icon_default).showImageOnFail(R.drawable.live_icon_default)//加载中、加载错误时显示的图片 .bitmapConfig(Bitmap.Config.RGB_565).build(); setContentView(R.layout.layout_main); mList = new ArrayList<LiveBean>(); loadingData(); gridView = (GridView) findViewById(R.id.gv); adapter = new MyBaseAdapter(); gridView.setAdapter(adapter); }
private void loadingData() { RequestParams requestParams = new RequestParams(); requestParams.put("page_index", "0");//非必须 requestParams.put("version", "1");//非必须 AsyncHttpHelper.get(SERVER_URL,RQ_LIVE, requestParams, new OnHttpListener<JSONObject>() {//http://api.95xiu.com/show/anchor_list_v3.php @Override public void onHttpListener(boolean httpSuccessed, JSONObject obj) { if (httpSuccessed) { Log.i("bqt", obj.toString()); if (obj.optInt("result") == 1) { JSONArray arr = obj.optJSONArray("user_info"); if (arr != null && arr.length() > 0) { for (int i = 0; i < arr.length(); i++) { JSONObject jObject = arr.optJSONObject(i); mList.add(new LiveBean(jObject.optString("anchor_image"), jObject.optString("nickname"), jObject.optString("live_num")// , jObject.optString("uid"))); } Log.i("bqt", "数据个数:" + mList.size()); } adapter.notifyDataSetChanged(); } } } }); }
public class MyBaseAdapter extends BaseAdapter { private ViewHolder mViewHolder; @Override public int getCount() { return mList == null ? 0 : mList.size(); } @Override public Object getItem(int position) { return mList == null ? null : mList.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(final int position, View convertView, ViewGroup parent) { if (convertView != null) mViewHolder = (ViewHolder) convertView.getTag(); else { convertView = LayoutInflater.from(MainActivity.this).inflate(R.layout.item, null); mViewHolder = new ViewHolder(); mViewHolder.iv_head = (ImageView) convertView.findViewById(R.id.iv_anchor_img); mViewHolder.tv_name = (TextView) convertView.findViewById(R.id.tv_anchor_name); mViewHolder.tv_audience_num = (TextView) convertView.findViewById(R.id.tv_audience_num); mViewHolder.iv_rankingLev = (ImageView) convertView.findViewById(R.id.iv_rankingLev); mViewHolder.iv_moods = (ImageView) convertView.findViewById(R.id.iv_moods); mViewHolder.iv_coverage = (ImageView) convertView.findViewById(R.id.iv_coverage); convertView.setTag(mViewHolder); } if (mList != null) { ImageLoader.getInstance().displayImage(mList.get(position).anchor_image, mViewHolder.iv_head, options); mViewHolder.tv_name.setText(mList.get(position).nickname); mViewHolder.tv_audience_num.setText(mList.get(position).live_num); if (position == 0) mViewHolder.iv_rankingLev.setVisibility(View.VISIBLE); else mViewHolder.iv_rankingLev.setVisibility(View.INVISIBLE); if (position == 0 || position == 1 || position == 3 || position == 6) mViewHolder.iv_moods.setVisibility(View.VISIBLE); else mViewHolder.iv_moods.setVisibility(View.INVISIBLE); mViewHolder.iv_coverage.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(MainActivity.this, LiveActivity.class); intent.putExtra("anchorId", mList.get(position).anchorId); Log.i("bqt", "主播ID:" + mList.get(position).anchorId); startActivity(intent); } }); } return convertView; } }
public static class ViewHolder { public ImageView iv_head;//主播头像 public TextView tv_name;//主播名字 public TextView tv_audience_num;//直播间人数 public ImageView iv_rankingLev;//排名 public ImageView iv_moods;//人气等标签 public ImageView iv_coverage;//背景框 } }
class LiveBean { public String anchor_image; public String nickname; public String live_num; public String anchorId; public LiveBean(String anchor_image, String nickname, String live_num, String anchorId) { super(); this.anchor_image = anchor_image; this.nickname = nickname; this.live_num = live_num; this.anchorId = anchorId; } }
布局
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:baselineAligned="false" android:background="#fff" android:orientation="horizontal" > <GridView android:id="@+id/gv" android:layout_width="match_parent" android:layout_height="wrap_content" android:cacheColorHint="#00000000" android:listSelector="#00000000" android:verticalSpacing="5dp" android:horizontalSpacing="5dp" android:descendantFocusability ="beforeDescendants" android:numColumns="2" /> </LinearLayout>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/rl_item" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#fbf7ed" > <ImageView android:id="@+id/iv_anchor_img" android:layout_width="match_parent" android:layout_height="130dp" android:layout_alignParentTop="true" android:scaleType="fitXY" android:src="@drawable/live_icon_default" /> <ImageView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignBottom="@id/iv_anchor_img" android:background="@drawable/main_live_head_bg" /> <TextView android:id="@+id/tv_audience_num" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@id/iv_anchor_img" android:layout_alignParentLeft="true" android:layout_marginBottom="4dp" android:drawableLeft="@drawable/living_true" android:drawablePadding="4dp" android:ellipsize="end" android:gravity="center" android:paddingLeft="8dp" android:singleLine="true" android:text="111" android:textColor="#00f" android:textSize="12sp" /> <TextView android:id="@+id/tv_anchor_name" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignBottom="@id/tv_audience_num" android:layout_alignParentRight="true" android:layout_marginLeft="5dp" android:layout_toRightOf="@id/tv_audience_num" android:ellipsize="end" android:gravity="right" android:paddingRight="8dp" android:singleLine="true" android:text="这是主播主播主播" android:textColor="#fff" android:textSize="12sp" /> <ImageView android:id="@+id/iv_rankingLev" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_marginLeft="4dp" android:layout_marginTop="8dp" android:src="@drawable/live_ranking1" /> <ImageView android:id="@+id/iv_moods" android:layout_width="40dp" android:layout_height="17dp" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:layout_marginTop="8dp" android:src="@drawable/live_moods" /> <ImageView android:id="@+id/iv_coverage" android:layout_width="match_parent" android:layout_height="130dp" android:background="@drawable/live_main_item_bg" android:clickable="true" android:focusable="true" /> </RelativeLayout>
Activity_直播
public class LiveActivity extends Activity { private ViEAndroidGLES20 mSurfaceView; private LinearLayout root; private String mVideoUrl; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE);//取消标题栏 initViews(); setContentView(root); } private void initViews() { // 视频比率 4:3 DisplayMetrics displayMetrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); int width = displayMetrics.widthPixels; int h = width * 3 / 4; if (h % 2 != 0) h += 1; root = new LinearLayout(this); root.setOrientation(LinearLayout.VERTICAL); mSurfaceView = ViERenderer.CreateRenderer(this, true, null); mSurfaceView.setLayoutParams(new FrameLayout.LayoutParams(width, h));//具有父控件的View设置setLayoutParams才有效! root.addView(mSurfaceView); TextView textView = new TextView(this); root.addView(textView); Intent intent = getIntent(); if (intent != null && intent.getStringExtra("anchorId") != null) { mVideoUrl = String.format("app/%s?k=1092dc67c9402014144fc19181974172&t=540fb568", intent.getStringExtra("anchorId")); textView.setText("视频地址:" + mVideoUrl); //livestream.setPlayerStateHandler(mHandler); livestream.init(mVideoUrl, mSurfaceView); startVideo(); } }
public void startVideo() { try { Log.v("vvvv", "startPlay"); livestream.setVideoPath(mVideoUrl); livestream.setSurfaceView(mSurfaceView); livestream.playVideo(); } catch (Exception e) { e.printStackTrace(); } } public void stopVideo(boolean isFreeHandler) { try { Log.v("vvvv", "stopPlay"); livestream.stopVideo(); if (isFreeHandler) { livestream.setPlayerStateHandler(null); } } catch (Exception e) { e.printStackTrace(); } } public static void freeVideo() { try { livestream.setPlayerStateHandler(null); livestream.free(); } catch (Exception e) { e.printStackTrace(); } }
@Override public void onPause() { super.onPause(); } @Override public void onDestroy() { super.onDestroy(); if (mSurfaceView != null) mSurfaceView.onPause(); stopVideo(true); } }
清单文件
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.bqt.test" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="21" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <activity android:name=".MainActivity" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".LiveActivity" > </activity> </application> </manifest>
附件列表
时间: 2024-10-10 08:12:40