【直播】基本实现

基本架构


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>

来自为知笔记(Wiz)

附件列表

时间: 2024-10-10 08:12:40

【直播】基本实现的相关文章

微信视频直播方案的搭建

实现在微信中嵌入直播视频,可以分享到好友或朋友圈. 工具/原料 NTV Media Server G3软件 Adobe Flash Encoder OBS直播软件 方法/步骤 1 可以使用百度.阿里或腾讯云主机,基本配置: CPU:2核心 内存:4GB 存储:50GB 带宽:10Mbps 2 或者准备一台硬件设备用于安装流媒体服务器软件,基本配置要求: CPU:Intel 至强系列,或者Intel i3以上性能的CPU 内存:16GB 存储:500GB 网卡:千兆网卡 3 安装操作系统,推荐安装

在“春晚”夹击中实现差异化突围 一直播春节系列活动吸睛

自1983年举办至今,央视春节联欢晚会已经成为了中国规模最大.最受关注.收视率最高.影响力最大的综艺晚会.就在2017鸡年央视春晚上,截止当晚22时30分网络收看人数达1.04亿,手机和移动端占比超七成.鸡年春晚除了延续品牌神话外,也给在移动端上和春晚同台竞技的直播平台们带来了巨大的挑战. 截止除夕夜12时,一直播独家策划的"直播过大年"春节直播活动累计观看次数突破6600万,最高同时在线峰值突破450万:同时,持续数十天的一直播"星拜年"活动,已有超过150位明星

用java写一个远程视频监控系统,实时监控(类似直播)我想用RPT协议,不知道怎么把RPT协议集成到项目中

我最近在用java写一个远程视频监控系统,实时监控(类似直播)我想用RPT协议,不知道怎么把RPT协议集成到项目中,第一次写项目,写过这类项目的多多提意见,哪方面的意见都行,有代码或者demo的求赏给我,谢谢

【直播预告】云栖直播:阿里热修复产品HotFix2.0升级详解

全面--你知道吗?1891年,卡尔森纳做出的第一把瑞士军刀,只有螺丝刀和开罐器.经过一代又一代能工巧匠的打磨,这把刀陆续增加了锯子.剪刀.镊子.放大镜.改锥,甚至内藏激光.LED手电筒.USB记忆碟等功能. 稳定--你知道吗?公元前1500多年前,埃及人就已经用绳子和竖棍做成了简易天平,成为现代天平的雏型.天平是平衡的象征,托盘内不断增加的砝码,更是自信与质量的保障. 精准--你知道吗?1608年,荷兰眼镜商汉斯·利伯希用两块镜片发明了人类历史上第一架望远镜,随着技术的发展,大千世界在人类的探索

手把手教你视频直播开发

#pragma mark viewDidLoad - (void)viewDidLoad { [super viewDidLoad]; self.liveRoomVC = LiveRoomVC_LiveRoomViewController; self.isTouchHomeEd = NO; NSLog(@"!!!%ld",(long)self.staruserid); [AppDelegate shareAppDelegate].isNeedReturnLiveRoom = YES;

关东升终身会员特惠1980,购买即赠价值1599元WOT峰会门票一张+价值2200元Cocos2D-x直播课!

亲爱的学员:        您好!关东升会员限时特惠啦!6月8日前特惠1980元(原价3000元)即可成为终身会员,观看所有付费课程(包括将来要推出的).现在购买还赠送价值2200元Cocos2D-x直播课程!7月18日前购买还赠价值1599元WOT峰会门票一张哟>> 成为关东升会员,您能够获得以下权益:1.亲笔签名iOS高端系列图书一本 : 2.能够学习关老师现有课程和录制的最新课程: 3.提供AppStore开发者账号,帮助学员上线自己开发的App4.享受24小时讲师在线答疑,提供iOS学

商城导购直播系统怎么做

商城导购直播系统为什么被商家推行 1.导购操作简便,和现场给用户讲解和回复咨询几乎一样,没有使用障碍和心理障碍,无须专业培训,上手快. 2.和线上的电商平台关联后消费者可以直接下单购买并和导购业绩挂勾,解决利益分配问题. 3.用户购买时才会进入直播场景,平时不会受到导购所谓的刷屏影响. 4.年轻消费群体的热爱和认同,90后一代的导购和消费群体都属于要真实要个性的一代.直播的真实.互动和有趣让90后导购和90后消费者相互的认同感更强,更好地促进销售的转化,至于销售是到店买还是线上买反而已经不重要了

Android IOS WebRTC 音视频开发总结(七六)-- 探讨直播低延迟低流量的粉丝连麦技术

本文主要探讨基于WebRTC的P2P直播粉丝连麦技术 (作者:郝飞,亲加云CTO,编辑:dora),最早发表在[这里] 支持原创,转载必须注明出处,欢迎关注微信公众号blacker(微信ID:blackerteam  或 webrtcorgcn) 到目前为止,直播行业继续如预期的那样如火如荼的发展着,在先后竞争完延迟,高清,美 颜,秒开等功能后,最近各大直播平台比拼的一个热点就是连麦.什么是连麦? 简单??述 就是当主播直播期间,可以与其中某一个粉丝进行互动,并且其他粉丝能够观看到这个互动 过程

花椒直播投资1亿发力专业PGC 携央视、SMG创建直播内容新生态

在经历了"跑马圈地"和"野蛮生长"的上半场,直播行业全面进入整合期.平台内容同质化愈加显现竞争疲态,而以专业PGC为核心的精品内容战略成为各大直播平台在新阶段的发展共识.据悉,前不久完成10亿元融资的花椒直播,继全面进军游戏领域后,又被曝出投入1亿资金用于专业PGC内容的引入与扶持,引发业内外广泛关注. 与SMG.央视合作 打造现象级专业PGC范例 "联合最顶尖的内容团队,引进内容IP,是今年PGC内容拓展的重中之重."花椒相关负责人介绍,&qu

稳定在线流畅直播软件开发

小程序视频直播系统软件,小程序视频直播软件开发,小程序视频直播平台开发,小程序视频直播程序开发,小程序视频直播商城开发,小程序视频直播技术开发. 开发咨询:185-2945-7803陈生(微电同号) 小程序系统 小程序视频直播系统是一个以直播和小视频内容引爆销售的全渠道营销工具,集小视频.直播电商.全渠道裂变分销.SCRM粉丝管理.深度数据分析为一体 帮助商家一分钟开设直播或小视频内容商店,一键跨平台并发将店铺同时开到微信.微博.QQ等社交媒体,全渠道裂变分销,精准运营粉丝社群,轻松激活消费者复