6、 流媒体开发之-直播界面切换电视台频道

网上大多数直播软件都会提供一个功能就是自定义,这个由于版本问题,而为了让用户看到自己想看的频道,可以让用户自己添加找到的源,然后进行播放,俗话说法不责众,这个功能是如何实现的呢,其实也是很简单的,无法就是记录下用户添加的数据,然后保存下来,这里主要用到了数据库,用户点击自己添加的源,程序会从数据库取出链接,例如http,rtsp等开头的流媒体链接,具体的实现如下,我们是在之前 流媒体开发之--直播实现 的基础上继续完善。

首先就是设计一个布局,里面使用ListView来填充,custom.xml,内容如下:

<?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:orientation="vertical" >
    <TextView 
        android:id="@+id/custom_title"
        android:layout_width="match_parent"
        android:layout_height="30dp"
        android:text="直播"
        android:textSize="27sp"
        android:gravity="center"
    <ListView 
        android:id="@+id/custom_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        ></ListView>
</LinearLayout>


我们同时还需要一个ListView的一个Item和一个foot用来显示添加的源和实现添加功能,内容如下:

custom_list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal" >
    <TextView 
        android:id="@+id/custom_list_item_name"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:singleLine="true"
        android:text="频道"
	<TextView 
	    android:id="@+id/custom_list_item_url"
	    android:layout_width="match_parent"
	    android:layout_height="30dp"
	    android:text="视频源链接"
</LinearLayout>


custom_list_foot.xml

<?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:orientation="vertical" >
    <TextView 
        android:layout_width="match_parent"
        android:layout_height="30dp"
        android:text="点击此处添加视频源"
        android:textSize="25sp"
</LinearLayout>


我上面只是使用TextView来显示,如果需要美化,可以添加ImageView来实现图文并茂,布局写完后,我们就要添加一个数据库用来记录添加的视频源,为了方便起见,我们还需要定义一个自定义视频内容格式的类,内容如下:

CustomVideo.java

package com.jwzhangjie.live.type;
import java.io.Serializable;
public class CustomVideo implements Serializable{
	private static final long serialVersionUID = 2166585200370610099L;
	private String name;
	private String url;
	public String getName() {
		return name;
	public void setName(String name) {
		this.name = name;
	public String getUrl() {
		return url;
	public void setUrl(String url) {
		this.url = url;

DBHelper.java

package com.jwzhangjie.live.db;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
public class DBHelper extends SQLiteOpenHelper{
	public static final String DB_NAME = "custom.sqlite";
	public static final String TABLE_NAME_VIDEO = "custom";
	public static final String CAMERA_SQL = "CREATE TABLE video ('_id' INTEGER PRIMARY KEY  AUTOINCREMENT, 'name' VARCHAR, 'url' VARCHAR)";
	public static int DB_VERSION = 1;
	public DBHelper(Context context, String name, CursorFactory factory,
			int version) {
		super(context, DB_NAME, null, DB_VERSION);
	@Override
	public void onCreate(SQLiteDatabase db) {
		db.execSQL(CAMERA_SQL);
	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

当然有这个还不行,我们还需要创建一个实现数据库各种操作的类,定义如下:

package com.jwzhangjie.live.utils;
import java.util.ArrayList;
import java.util.List;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import com.jwzhangjie.live.db.DBHelper;
import com.jwzhangjie.live.type.CustomVideo;
public class DBUtils {
	private static DBHelper mDbHelper;
	public DBUtils(Context context){
		mDbHelper = new DBHelper(context);
	 * insert custom video
	public void insertCustomVideo(CustomVideo customVideo){
		SQLiteDatabase dbDatabase = null;
		try {
			dbDatabase = mDbHelper.getWritableDatabase();
			if (dbDatabase == null) {
				return;
			ContentValues contentValues = new ContentValues();
			contentValues.put("name", customVideo.getName());
			contentValues.put("url", customVideo.getUrl());
			dbDatabase.insertOrThrow("custom", null, contentValues);
		} catch (Exception e) {
		}finally{
			dbDatabase.close();
	public void deleteOneCustomVideo(String name){
		SQLiteDatabase dbDatabase = mDbHelper.getWritableDatabase();
		try {
			String sql = "DELETE FROM custom WHERE name = "+name;
			dbDatabase.execSQL(sql);
		} catch (Exception e) {
		}finally{
			dbDatabase.close();
	public List<CustomVideo> getAllCameras(){
		List<CustomVideo> list = new ArrayList<CustomVideo>();
		SQLiteDatabase dbDatabase = mDbHelper.getWritableDatabase();
		String sql = "SELECT * FROM custom";
		Cursor cursor = dbDatabase.rawQuery(sql, null);
		while (!cursor.isLast()) {
			cursor.moveToNext();
			CustomVideo video = new CustomVideo();
			video.setId(cursor.getInt(0));
			video.setName(cursor.getString(1));
			video.setUrl(cursor.getString(2));
			list.add(video);
		dbDatabase.close();
		return list;
	public int getAllCustomVideoCount(){
		SQLiteDatabase db = mDbHelper.getReadableDatabase();
		Cursor cursor = db.rawQuery("select count(*) from custom", null);
		cursor.moveToNext();
		int count = cursor.getInt(0);
		cursor.close();
		db.close();
		return count;


做完上述事情后,我们就要设计显示界面操作,首先就是适配器的设计:

package com.jwzhangjie.live.utils;

import java.util.ArrayList; import java.util.List;

import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase;

import com.jwzhangjie.live.db.DBHelper; import com.jwzhangjie.live.type.CustomVideo;

public class DBUtils {

 public static DBHelper mDbHelper;  public DBUtils(Context context){   mDbHelper = new DBHelper(context);   * insert custom video  public void insertCustomVideo(CustomVideo customVideo){   SQLiteDatabase dbDatabase = null;   try {    dbDatabase = mDbHelper.getWritableDatabase();    if (dbDatabase == null) {     return;    ContentValues contentValues = new ContentValues();    contentValues.put("name", customVideo.getName());    contentValues.put("url", customVideo.getUrl());    dbDatabase.insertOrThrow("custom", null, contentValues);   } catch (Exception e) {   }finally{    dbDatabase.close();  public void deleteOneCustomVideo(String url){   SQLiteDatabase dbDatabase = mDbHelper.getWritableDatabase();   try {    String sql = "DELETE FROM custom WHERE url = "+url;    dbDatabase.execSQL(sql);   } catch (Exception e) {   }finally{    dbDatabase.close();  public List<CustomVideo> getAllCameras(){   List<CustomVideo> list = new ArrayList<CustomVideo>();   SQLiteDatabase dbDatabase = mDbHelper.getWritableDatabase();   String sql = "SELECT * FROM custom";   Cursor cursor = dbDatabase.rawQuery(sql, null);   while (!cursor.isLast()) {    cursor.moveToNext();    CustomVideo video = new CustomVideo();    video.setId(cursor.getInt(0));    video.setName(cursor.getString(1));    video.setUrl(cursor.getString(2));    list.add(video);   dbDatabase.close();   return list;  public int getAllCustomVideoCount(){   SQLiteDatabase db = mDbHelper.getReadableDatabase();   Cursor cursor = db.rawQuery("select count(*) from custom", null);   cursor.moveToNext();   int count = cursor.getInt(0);   cursor.close();   db.close();   return count;

适配器设置完毕后,我们剩下显示界面了

package com.jwzhangjie.live;
import java.util.ArrayList;
import java.util.List;
import com.jwzhangjie.live.adapter.CustomVideoAdapter;
import com.jwzhangjie.live.type.CustomVideo;
import com.jwzhangjie.live.utils.DBUtils;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
public class CustomVideoList extends Activity implements OnItemClickListener, OnClickListener{
	public ListView customVideoListView;
	public CustomVideoAdapter listAdapter;
	private List<CustomVideo> listVideos;
	public Button addBtn;
	public EditText addUrl;
	DBUtils dbUtils = new DBUtils(this);
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.custom);
		addBtn = (Button)findViewById(R.id.add);
		addUrl = (EditText)findViewById(R.id.addurl);
		customVideoListView = (ListView)findViewById(R.id.custom_list);
		listAdapter = new CustomVideoAdapter(this);
		customVideoListView.setAdapter(listAdapter);
		customVideoListView.setOnItemClickListener(this);
		addBtn.setOnClickListener(this);
		addUrl.setText("http://74.82.62.53:1935/liverepeater/10.stream/playlist.m3u8");
		int size = dbUtils.getAllCustomVideoCount();
		if (size != 0) {
			listVideos = dbUtils.getAllCameras();
			listAdapter.setCustomVideoList(listVideos);
		}else {
			listVideos = new ArrayList<CustomVideo>();
	@Override
	protected void onResume() {
		super.onResume();
	@Override
	public void onClick(View v) {
		if (v == addBtn) {
			if (addUrl.getText() != null) {
				CustomVideo customVideo = new CustomVideo();
				customVideo.setName("视频");
				customVideo.setUrl(addUrl.getText().toString());
				dbUtils.insertCustomVideo(customVideo);
				listAdapter.insertCustomVideo(customVideo);
				listVideos.add(customVideo);
	@Override
	public void onItemClick(AdapterView<?> parent, View view, int position,
			long id) {
		Intent intent = new Intent();
		intent.setClass(CustomVideoList.this, JieVideoPlayer.class);
		intent.putExtra("path", listVideos.get(position).getUrl());
		startActivity(intent);


效果如下:

点击你选择的视频也能够播放视频,自定义功能就这些。

网上大多数直播软件都会提供一个功能就是自定义,这个由于版本问题,而为了让用户看到自己想看的频道,可以让用户自己添加找到的源,然后进行播放,俗话说法不责众,这个功能是如何实现的呢,其实也是很简单的,无法就是记录下用户添加的数据,然后保存下来,这里主要用到了数据库,用户点击自己添加的源,程序会从数据库取出链接,例如http,rtsp等开头的流媒体链接,具体的实现如下,我们是在之前流媒体开发之--直播实 将广告资源上传到Google表格 playlist inventory spotify:playlist:4lU91kdjtDgkQxwSbPE77U 使用JMESpath将json文件仅搜索到的字段更新 playtlist inventory --playlist spotify:playlist:4lU91kdjtDgkQxwSbPE77U --format value --fields " [*][track.name, track.album.name, track.album.artists[0].name] " playlist inventory --playlist spotify:playlist:4lU
最近业余时间跟朋友要搞一个流媒体直播app,所以这段时间搜集一些资料,然后整理下来,同时有时也会将一些遇到的问题的解决方案记录下来,--因为分享,技术无处不在!首先这一章来讲解一下m3u8文件的格式,以及里面的内容含义。 1. Playlist file     一个M3U的 Playlist 就是一个由多个独立行组成的文本文件,每行由回车/换行区分。每一行可以是一个URI  空白
整合流媒体开发之-音悦台TV解析和流媒体开发之-音悦台TV页码链接解析这两部分来实现解析音乐台特定条件的所有TV视频链接。 package com.pigvideo.parser.yinyuetai; import com.pigvideo.model.YinYueTaiModel; import com.pigvideo.model.YinYueTaiPageModel; import o
由于工作问题写博客不能连贯,很多个人开发开发播放器的时候,基本上都是提供播放功能,没有提供网上资源,比较维护是很麻烦的,我们可以使用网上资源,最近业余在搞音乐部分,对于资源部分我也是使用网上现有的资源,比如音悦台里面有很多TV,我们可以解析他们的网页内容。下面就是解析其中一个网页的TV 首先确定你TV要实现的内容,封装一个类内容如下: package com.pigvideo.model;
### 回答1: SRS流媒体是一种流媒体服务器软件,可在Windows操作系统上运行。SRS代表Simple Realtime Server,它是一个开源的流媒体服务器,提供了高效的音视频传输和流媒体处理能力。 SRS流媒体服务器主要用于直播和点播服务。它支持常见的流媒体协议和格式,如RTMP、HLS、FLV和MP4。通过SRS,用户可以将音视频内容从源站点传输到客户端设备,使用户能够实时观看和听取流媒体内容。 在Windows系统上,SRS提供了简单易用的安装和配置过程。用户只需下载适用于Windows的SRS软件,并按照提供的指南进行安装。一旦安装完成,用户可以通过命令行或配置文件对SRS进行进一步的配置,以满足其特定的需求。 SRS流媒体服务器在Windows上具有良好的稳定性和可靠性,能够处理大量的并发连接和高负载。它提供了多种功能和特性,如性能监控、转码、水印、鉴权、录制等。用户可以根据自己的需求选择合适的配置和功能,以创建一个定制化的流媒体服务平台。 总之,SRS流媒体服务器在Windows操作系统上是一种可靠的选择,它提供了强大的音视频传输和流媒体处理能力,适用于各种直播和点播服务需求。无论是个人用户还是企业用户,都可以通过SRS轻松搭建自己的流媒体系统。 ### 回答2: SRS流媒体是一个开源流媒体服务器软件,可以在Windows操作系统上运行。它提供了丰富的功能,包括实时的音视频流传输、跨平台支持和高性能的编解码能力。 SRS流媒体可以用于搭建自己的流媒体服务平台,支持多种流媒体协议,如RTMP、HLS和HTTP-FLV等。不仅如此,它还支持动态转发、边缘节点传输和优质的流媒体传输控制,可以满足不同场景下的流媒体需求。 在Windows操作系统上安装和配置SRS流媒体相对简单。只需下载对应版本的SRS软件包,并按照官方文档提供的步骤进行安装和配置即可。SRS流媒体具有良好的兼容性,可以在不同版本的Windows系统上运行,并能与其他常用的流媒体软件和设备进行配合使用。 通过SRS流媒体,用户可以方便地实现音视频数据的分发和传输。无论是在线直播、点播还是视频会议等应用场景,SRS流媒体都能够提供稳定、高质量的流媒体传输服务。同时,SRS流媒体还支持自定义开发和定制功能,用户可以根据自己的需求进行二次开发和扩展。 总结起来,SRS流媒体适用于Windows操作系统,提供了强大的功能和稳定的流媒体传输服务,可以满足各种不同的流媒体应用需求。无论是个人、企业还是机构,都可以使用SRS流媒体搭建自己的流媒体平台,实现高质量的音视频传输和流媒体服务。