Samba协议实现视频上传、远程播放
一、效果演示
扫码打开上传页面,上传进度可以全局筛选订单查看,上传过程中查看视频是本地视频(速度快),上传完成后再次打开是smb服务器视频(打开慢)
本文涉及demo参考下载
二、集成smbj
1、集成smbj
java使用samba协议,主要用到了smbj库
gradle集成
implementation 'com.hierynomus:smbj:0.10.0'
maven集成
<dependency><groupId>com.hierynomusgroupId><artifactId>smbjartifactId><version>0.10.0version>
dependency>
2、maven测试工程创建
直接在项目中测试比较麻烦,最好新建一个maven工程测试。如果初次新建maven项目,则需要配置仓库源为阿里镜像,并同步。
settings.xml
<settings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://maven.apache.org/SETTINGS/1.2.0"xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.2.0 https://maven.apache.org/xsd/settings-1.2.0.xsd"><mirrors><mirror><id>nexus-aliyunid><mirrorOf>centralmirrorOf><name>Nexus aliyunname><url>http://maven.aliyun.com/nexus/content/groups/publicurl>mirror>mirrors>
settings>
三、smb操作
1、初始化连接配置
如果有上传流的操作,则需要开启共享读写,否则会造成文件一直被暂用情况(当然也可以让这个客户端断开连接)
public static void main(String[] args) throws Exception {String ip = "192.168.1.114";String userName = "";String password = "";String shareDir = "share";SMBClient client = new SMBClient();try (Connection connection = client.connect(ip)) {AuthenticationContext ac = new AuthenticationContext(userName, password.toCharArray(), "");Session session = connection.authenticate(ac);// Connect to Sharetry (DiskShare share = (DiskShare) session.connectShare(shareDir)) {Set<FileAttributes> fileAttributes = new HashSet<>();fileAttributes.add(FileAttributes.FILE_ATTRIBUTE_NORMAL);fileAttributes.add(FileAttributes.FILE_ATTRIBUTE_ARCHIVE);Set<SMB2CreateOptions> createOptions = new HashSet<>();createOptions.add(SMB2CreateOptions.FILE_NO_COMPRESSION);createOptions.add(SMB2CreateOptions.FILE_RANDOM_ACCESS);// 共享读、共享写Set<SMB2ShareAccess> smb2ShareAccesses = new HashSet<>();smb2ShareAccesses.add(SMB2ShareAccess.FILE_SHARE_WRITE);smb2ShareAccesses.add(SMB2ShareAccess.FILE_SHARE_READ);// 连接成功}} catch (Exception e) {e.printStackTrace();}
}
2、文件上传
/*** 上传文件到远程** @param host IP地址* @param username 用户名* @param password 用户密码* @param path 共享目录* @param innerDir 远程内部文件夹* @param localFileName 本地文件*/
public static void uploadFile(String host, String username, String password, String path, String innerDir, String localFileName) {DiskShare share = getDiskShare(host, username, password, path);try {// 如果目录不存在,逐层创建createRemoteDir(share, innerDir);Set<AccessMask> accessMasks = new HashSet<>();accessMasks.add(AccessMask.FILE_ADD_FILE);Set<FileAttributes> attributes = new HashSet<>();attributes.add(FileAttributes.FILE_ATTRIBUTE_NORMAL);Set<SMB2ShareAccess> smb2ShareAccesses = new HashSet<>();smb2ShareAccesses.add(SMB2ShareAccess.FILE_SHARE_WRITE);smb2ShareAccesses.add(SMB2ShareAccess.FILE_SHARE_READ);Set<SMB2CreateOptions> smb2CreateOptions = new HashSet<>();smb2CreateOptions.add(SMB2CreateOptions.FILE_RANDOM_ACCESS);// 文件名称: "tempDir/测试.mp4"String fileName = innerDir + "/" + localFileName.substring(localFileName.lastIndexOf("/") + 1);com.hierynomus.smbj.share.File openFile = share.openFile(fileName, accessMasks, attributes, smb2ShareAccesses, SMB2CreateDisposition.FILE_OVERWRITE_IF, smb2CreateOptions);OutputStream oStream = openFile.getOutputStream();BufferedInputStream in = new BufferedInputStream(new FileInputStream(localFileName));byte[] buffer = new byte[1024*1024];int len = 0; //Read lengthwhile ((len = in.read(buffer, 0, buffer.length)) != -1) {oStream.write(buffer, 0, len);}oStream.flush();oStream.close();} catch (Exception e) {e.printStackTrace();}
}
3、创建远程文件夹
/*** 创建远程目录** @param share* @param dirName*/
private static void createRemoteDir(DiskShare share, String dirName) {// 是否已存在if (share.folderExists(dirName)) {return;}// 目录不存在,逐层创建String[] fileNameArr = dirName.split("/");String tempDirName = ""; // 逐层目录for (String fileName : fileNameArr) {tempDirName += fileName + "/"; // 下一层目录if (share.folderExists(tempDirName)) {continue;}System.out.println("目录: " + tempDirName + " 不存在,即将创建");share.mkdir(tempDirName);}
}
4、下载远程文件
/*** 下载远程文件** @param host IP地址* @param username 用户名* @param password 用户密码* @param path 共享目录* @param remoteFile 远程文件, 可以是具体的文件,可以是匹配的文件* @param localDir 本地目标目录*/
public static void downloadFile(String host, String username, String password, String path, String remoteFile, String localDir) {DiskShare share = getDiskShare(host, username, password, path);// 添加文件夹分隔符localDir = checkDirEnd(localDir);try {// 文件夹是否存在,创建本地目录createLocalDirIfNotExist(localDir);String remoteDir = "";for (FileIdBothDirectoryInformation f : share.list(remoteDir, remoteFile)) {String filePath = f.getFileName();String dstPath = localDir + f.getFileName();FileOutputStream fos = new FileOutputStream(dstPath);BufferedOutputStream bos = new BufferedOutputStream(fos);if (share.fileExists(filePath)) {System.out.println("正在下载文件: " + f.getFileName());com.hierynomus.smbj.share.File smbFileRead = share.openFile(filePath, EnumSet.of(AccessMask.GENERIC_READ), null, SMB2ShareAccess.ALL, SMB2CreateDisposition.FILE_OPEN, null);InputStream in = smbFileRead.getInputStream();byte[] buffer = new byte[4096];int len = 0;while ((len = in.read(buffer, 0, buffer.length)) != -1) {bos.write(buffer, 0, len);}bos.flush();bos.close();System.out.println("文件下载成功, 保存在 " + dstPath);} else {System.out.println("文件 " + filePath + " 不存在");}}} catch (Exception e) {System.out.println("文件下载失败");e.printStackTrace();}
}
5、服务器拷贝
这个是通过磁盘IO,没有经过网络,速度可以达到几百MB每秒
String filePath1 = "wenjing/test/1.mp4";
File file1 = share.openFile(filePath1, EnumSet.of(AccessMask.GENERIC_READ), fileAttributes, SMB2ShareAccess.ALL, SMB2CreateDisposition.FILE_OPEN_IF, createOptions);String filePath2 = "wenjing/test/1_jdk15.mp4";
File file2 = share.openFile(filePath2, EnumSet.of(AccessMask.GENERIC_WRITE), fileAttributes, SMB2ShareAccess.ALL, SMB2CreateDisposition.FILE_CREATE, createOptions);file1.remoteCopyTo(file2);
6、更多功能与备注
更多功能:除了上述功能外,smb还支持list查看文件夹,删除文件夹、文件等
备注:在实际使用过程中,发现smbj库对于系统仍然有区别
1、macOS共享的smb:不支持服务器拷贝、不支持创建文件夹
2、linux共享的smb:一切正常
四、播放smb视频
播放smb链接视频需要用到vlc库,这个库相对较大(大概三十几MB),但是体验比自己写的流稳定。
implementation 'com.yyl.vlc:vlc-android-sdk:3.3.0'
跳转播放页面
Intent intent = new Intent(mContext, VlcPlayerActivity.class);
String path = "smb://dabaojiqi:0429@192.168.1.114/mac/tempDir/测试.mp4";
intent.putExtra("videoPlayPath", path);
mContext.startActivity(intent);
VlcPlayerActivity相关android项目下载参考前面的"一、效果演示",内附demo下载链接
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
