欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 美食 > Android 播放SMB共享视频

Android 播放SMB共享视频

2025/1/19 20:50:41 来源:https://blog.csdn.net/zjuter/article/details/145160855  浏览:    关键词:Android 播放SMB共享视频

表面上看MediaPlayer只能播放本地和http协议视频。没有直接支持smb://协议。那还能播放smb视频呢?也可以的!

MediaPlayer有一个方法叫:setDataSource(MediaDataSource)。

    /*** Sets the data source (MediaDataSource) to use.** @param dataSource the MediaDataSource for the media you want to play* @throws IllegalStateException if it is called in an invalid state* @throws IllegalArgumentException if dataSource is not a valid MediaDataSource*/public void setDataSource(MediaDataSource dataSource)throws IllegalArgumentException, IllegalStateException {_setDataSource(dataSource);}

我们只要实现MediaDataSource这个接口就可以了。

/*** For supplying media data to the framework. Implement this if your app has* special requirements for the way media data is obtained.** <p class="note">Methods of this interface may be called on multiple different* threads. There will be a thread synchronization point between each call to ensure that* modifications to the state of your MediaDataSource are visible to future calls. This means* you don't need to do your own synchronization unless you're modifying the* MediaDataSource from another thread while it's being used by the framework.</p>*/
public abstract class MediaDataSource implements Closeable {/*** Called to request data from the given position.** Implementations should fill {@code buffer} with up to {@code size}* bytes of data, and return the number of valid bytes in the buffer.** Return {@code 0} if size is zero (thus no bytes are read).** Return {@code -1} to indicate that end of stream is reached.** @param position the position in the data source to read from.* @param buffer the buffer to read the data into.* @param offset the offset within buffer to read the data into.* @param size the number of bytes to read.* @throws IOException on fatal errors.* @return the number of bytes read, or -1 if end of stream is reached.*/public abstract int readAt(long position, byte[] buffer, int offset, int size)throws IOException;/*** Called to get the size of the data source.** @throws IOException on fatal errors* @return the size of data source in bytes, or -1 if the size is unknown.*/public abstract long getSize() throws IOException;
}

下面是我实现的代码:

public class CustomMediaDataSource extends MediaDataSource {private static Logger Log4j = Logger.getLogger(CustomMediaDataSource.class);private SmbRandomAccessFile mFile; // must not Main UI thread.private long mFileSize;public CustomMediaDataSource(SmbRandomAccessFile smbFile, long size) throws SmbException {this.mFile = smbFile;mFileSize = size;}@Overridepublic int readAt(long position, byte[] buffer, int offset, int size) throws IOException {if (mFile.getFilePointer() != position)mFile.seek(position);if (size <= 0)return 0;Log4j.info("CustomMediaDataSource, readAt, position:" + position);return mFile.read(buffer, 0, size);}@Overridepublic long getSize() throws IOException {return mFileSize;}@Overridepublic void close() throws IOException {mFileSize = 0;if (mFile != null) {mFile.close();mFile = null;}}
}

这里有一个小插曲, 导致花费了大半天时间。视频播放不能用InputStream接口,要用RandomAccess接口。因为视频播放的数据不是按顺序取的。不然就会报错:java.io.IOException: Prepare failed.: status=0x1。

如果你是其他播放器的, 同样也会有这样的接口提供给你。比如ljkPlayer等。

这个主题值得写一下,网上基本没有讲到。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com