DLNA 在本身的APP 中添加投屏功能

功能:讓本機的視頻在其餘設備上播放。java

demo 學習中node

關鍵詞: cling  git

demo from: DROID DLNA 服務器

關於投屏的原理,協議相關的知識已經在上一篇中說明。ide

關於設備搜索,查找等不在此處說明。學習

投屏系統中分: 設備 服務 控制點。url

當須要把A 設備中的視頻 投屏到 B 設備。rest

重點是:如何生成本地視頻的URL, 這樣才能經過 控制點 設置play url 到 播放端。code

跟蹤demo 代碼發現,播放的這個本地視頻,返回的是一個xml 數據。節點中提供了這些視頻的 thumb , url 。視頻

ContentDirectoryService

這個類中的browse 方法,實現了數據查詢和生成方法。

中間的代碼寫的很是複雜,在

MethodActionExecutor

中用了反射最終調用到這裏。 其中的兩個service(Local & remote 都不是真正的service)

 

本地文件的信息在初始化的時候就被所有掃描並添加進來:

ContentTree
addNode

而且生成了 每一個節點的url;

這是demo 中生成的 video item 節點

<item id="video-item-27559" parentID="1" restricted="0">
    <dc:title>SVID_20170929_115451</dc:title>
    <dc:creator>&lt;unknown&gt;</dc:creator>
    <upnp:class>object.item.videoItem</upnp:class>
    <upnp:albumArtURI>http://10.4.58.82:8192/storage/emulated/0/msi/.videothumb/video_thumb_video-item-27559.png</upnp:albumArtURI>
    <dc:description/>
    <res protocolInfo="http-get:*:video/mp4:*" size="123202814" duration="0:3:1" resolution="1280x720">http://10.4.58.82:8192/video-item-27559</res>
  </item>

這是demo 中生成單個播放ship video Item 的方法:

DevicesActivity
String id = ContentTree.VIDEO_PREFIX
						+ cursor.getInt(cursor
								.getColumnIndex(MediaStore.Video.Media._ID));
				String title = cursor.getString(cursor
						.getColumnIndexOrThrow(MediaStore.Video.Media.TITLE));
				String creator = cursor.getString(cursor
						.getColumnIndexOrThrow(MediaStore.Video.Media.ARTIST));
				String filePath = cursor.getString(cursor
						.getColumnIndexOrThrow(MediaStore.Video.Media.DATA));

				String mimeType = cursor
						.getString(cursor
								.getColumnIndexOrThrow(MediaStore.Video.Media.MIME_TYPE));
				long size = cursor.getLong(cursor
						.getColumnIndexOrThrow(MediaStore.Video.Media.SIZE));
				long duration = cursor
						.getLong(cursor
								.getColumnIndexOrThrow(MediaStore.Video.Media.DURATION));
				String resolution = cursor
						.getString(cursor
								.getColumnIndexOrThrow(MediaStore.Video.Media.RESOLUTION));

				String description = cursor
						.getString(cursor
								.getColumnIndexOrThrow(MediaStore.Video.Media.DESCRIPTION));

				Res res = new Res(new MimeType(mimeType.substring(0,
						mimeType.indexOf('/')), mimeType.substring(mimeType
						.indexOf('/') + 1)), size, "http://"
						+ mediaServer.getAddress() + "/" + id);

				res.setDuration(duration / (1000 * 60 * 60) + ":"
						+ (duration % (1000 * 60 * 60)) / (1000 * 60) + ":"
						+ (duration % (1000 * 60)) / 1000);
				res.setResolution(resolution);

				VideoItem videoItem = new VideoItem(id, ContentTree.VIDEO_ID,
						title, creator, res);

				// add video thumb Property
				String videoSavePath = ImageUtil.getSaveVideoFilePath(filePath,
						id);
				DIDLObject.Property albumArtURI = new DIDLObject.Property.UPNP.ALBUM_ART_URI(
						URI.create("http://" + mediaServer.getAddress()
								+ videoSavePath));
				Property[] properties = { albumArtURI };
				videoItem.addProperties(properties);
				videoItem.setDescription(description);
				videoContainer.addItem(videoItem);
				videoContainer
						.setChildCount(videoContainer.getChildCount() + 1);
				ContentTree.addNode(id,
						new ContentNode(id, videoItem, filePath));

 

HTTP 視頻播放服務:

電視會經過以前手機生成的 視頻節點信息中的Uri ,到手機端 請求視頻。

處理部分: HttpServer,這個文件是本身實現的,而不是cling 提供的。

 

String itemId = uri.replaceFirst("/", "");
		itemId = URLDecoder.decode(itemId);
		String newUri = null;
		
		if( ContentTree.hasNode(itemId) ) {
			ContentNode node = ContentTree.getNode(itemId);
			if (node.isItem()) {
				newUri = node.getFullPath();
			}
		}

 

 

一些其餘的關鍵詞:

DMS:Digital Media Server 數字媒體服務器

DMP:Digital Meidal Player : 播放器

DMC : Controller 控制器

DMR: Renderer  渲染器

相關文章
相關標籤/搜索