Так как все мои попытки потоковой передачи напрямую через VLC со ссылкой «sftp://» не увенчались успехом, мне удалось написать небольшую java-программу, которая бы выполняла именно то, что мне нужно, загружая файл и всегда проверяя размер удаленного файла изменился, чтобы возобновить загрузку, если это необходимо.
Ключом здесь является этот кусок кода:
sftpChannel.get(remotePath, outstream, monitor, ChannelSftp.OVERWRITE, 0);
long localSize;
Thread.sleep(1000);
while(sftpChannel.lstat(remotePath).getSize() > (localSize = new File(localPath).length())){
sftpChannel.get(remotePath, outstream, monitor, ChannelSftp.RESUME, localSize);
Thread.sleep(timeToWaitBeforeUpdatingFile);
}
System.out.println("The download is finished.");
Я также публикую весь код программы, если кому-то интересно:
package streamer;
import java.io.Console;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.Scanner;
import java.util.Vector;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
import com.jcraft.jsch.SftpProgressMonitor;
public class Streamer {
public static void main(String[] args) throws InterruptedException, IOException {
JSch jsch = new JSch();
if(args.length != 7){
System.out.println("Incorrect parameters:");
System.out.println("Streamer user host port privateKeyPath remotePath localPath vlcPath");
System.exit(-1);
}
String user = args[0];
String host = args[1];
int port = -1;
try {
port = Integer.parseInt(args[2]);
} catch (NumberFormatException e3) {
System.out.println("Port must be an integer");
System.exit(-1);
}
String privateKeyPath = args[3];
String remotePath = args[4];
String localPath = args[5];
String vlcPath = args[6];
int timeToWaitBeforeUpdatingFile = 5000;
String password = "";
Console console = System.console();
if (console == null) {
System.out.println("Couldn't get Console instance");
//password = "";
System.exit(-1);
}else{
char passwordArray[] = console.readPassword("Enter your password: ");
password = new String(passwordArray);
Arrays.fill(passwordArray, ' ');
}
try {
jsch.addIdentity(privateKeyPath, password);
} catch (JSchException e) {
System.out.println(e.getMessage());
System.out.println("Invalid private key file");
System.exit(-1);
}
Session session;
try {
session = jsch.getSession(user, host, port);
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
System.out.println("Establishing connection...");
session.connect();
System.out.println("Connection established.");
System.out.println("Creating SFTP Channel...");
ChannelSftp sftpChannel = (ChannelSftp) session.openChannel("sftp");
sftpChannel.connect();
System.out.println("SFTP Channel created.");
try {
@SuppressWarnings("unchecked")
Vector<ChannelSftp.LsEntry> recordings = sftpChannel.ls(remotePath + "*.mpeg");
if(recordings.isEmpty()){
System.out.println("There are no recordings to watch.");
System.exit(0);
}
int choice = 1;
System.out.println("Chose the recording to watch:");
for (ChannelSftp.LsEntry e : recordings){
System.out.println("[" + choice++ + "] " + e.getFilename());
}
Scanner sc = new Scanner(System.in);
try {
String fileName = recordings.get(sc.nextInt() - 1).getFilename();
remotePath += fileName;
localPath += fileName;
} catch (InputMismatchException e) {
System.out.println("Incorrect choice");
System.exit(-1);
}
System.out.println("You chose : " + remotePath);
sc.close();
} catch (SftpException e2) {
System.out.println("Error during 'ls': the remote path might be wrong:");
System.out.println(e2.getMessage());
System.exit(-1);
}
OutputStream outstream = null;
try {
outstream = new FileOutputStream(new File(localPath));
} catch (FileNotFoundException e) {
System.out.println("The creation of the file" + localPath + " failed. Local path is incorrect or writing permission is denied.");
System.exit(-1);
}
try {
SftpProgressMonitor monitor = null;
System.out.println("The download has started.");
System.out.println("Opening the file in VLC...");
try {
Runtime.getRuntime().exec(vlcPath + " " + localPath);
} catch (Exception ex) {
System.out.println("The file couldn't be opened in VLC");
System.out.println("Check your VLC path.");
System.out.println(ex);
}
sftpChannel.get(remotePath, outstream, monitor, ChannelSftp.OVERWRITE, 0);
long localSize;
Thread.sleep(1000);
while(sftpChannel.lstat(remotePath).getSize() > (localSize = new File(localPath).length())){
sftpChannel.get(remotePath, outstream, monitor, ChannelSftp.RESUME, localSize);
Thread.sleep(timeToWaitBeforeUpdatingFile);
}
System.out.println("The download is finished.");
outstream.close();
System.exit(0);
} catch (SftpException e1) {
System.out.println("Error during the download:");
System.out.println(e1.getMessage());
System.exit(-1);
}
} catch (JSchException e) {
System.out.println("Connection has failed (check the user, host, port...)");
System.exit(-1);
}
}
}