fflewddur / archivo Goto Github PK
View Code? Open in Web Editor NEWA cross-platform app for saving recordings from a TiVo to your computer.
Home Page: http://straylightlabs.net/archivo/
License: GNU General Public License v3.0
A cross-platform app for saving recordings from a TiVo to your computer.
Home Page: http://straylightlabs.net/archivo/
License: GNU General Public License v3.0
Currently the user can't refresh their recording list or change the selected TiVo to view another device while an archive operation is in progress. We can fix this by keeping a list of archive operations and matching it against the list of recordings fetched from each TiVo.
Avoid safety warnings by signing the Windows installer with a developer certificate.
Sorting by status is always overruled by the Date Recorded field.
Currently only a single recording can be selected at a time.
Investigate what it would take to support streaming recordings from a TiVo.
The Mac OS X installer should include a shortcut to the Applications folder and instructions to drag the Archivo app to that folder to install.
Steps to reproduce on OS X El Capitan:
Archivo will fail with the following stacktrace:
09:21:56.650 [pool-3-thread-1] INFO net.straylightlabs.archivo.Archivo - URL: http://192.168.29.121/download/Quantico.TiVo?Container=%2FNowPlaying&id=47150&Format=video/x-tivo-mpeg-ts
09:21:56.650 [pool-3-thread-1] INFO net.straylightlabs.archivo.Archivo - Saving file to /Users/rchavez/Movies/untitled folder/Quantico - S01E07 - Go.download.ts
09:21:56.671 [JavaFX Application Thread] INFO net.straylightlabs.archivo.Archivo - Setting status to 'Archiving Quantico โ Go...'
09:21:57.254 [pool-3-thread-1] INFO net.straylightlabs.archivo.Archivo - Status line: HTTP/1.1 200 File Follows
09:21:57.254 [pool-3-thread-1] INFO net.straylightlabs.archivo.Archivo - decrypt = true
09:21:57.260 [pool-3-thread-1] ERROR net.straylightlabs.archivo.Archivo - IOException while downloading recording:
java.nio.file.NoSuchFileException: /Users/rchavez/Movies/untitled folder/Quantico - S01E07 - Go.download.ts
at sun.nio.fs.UnixException.translateToIOException(UnixException.java:86) ~[na:1.8.0_65]
at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:102) ~[na:1.8.0_65]
at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:107) ~[na:1.8.0_65]
at sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:214) ~[na:1.8.0_65]
at java.nio.file.spi.FileSystemProvider.newOutputStream(FileSystemProvider.java:434) ~[na:1.8.0_65]
at java.nio.file.Files.newOutputStream(Files.java:216) ~[na:1.8.0_65]
at net.straylightlabs.archivo.controller.ArchiveTask.handleResponse(ArchiveTask.java:196) [Archivo.jar:na]
at net.straylightlabs.archivo.controller.ArchiveTask.getRecording(ArchiveTask.java:162) [Archivo.jar:na]
at net.straylightlabs.archivo.controller.ArchiveTask.archive(ArchiveTask.java:108) [Archivo.jar:na]
at net.straylightlabs.archivo.controller.ArchiveTask.call(ArchiveTask.java:86) [Archivo.jar:na]
at net.straylightlabs.archivo.controller.ArchiveTask.call(ArchiveTask.java:59) [Archivo.jar:na]
at javafx.concurrent.Task$TaskCallable.call(Task.java:1423) [jfxrt.jar:na]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_65]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_65]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_65]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_65]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_65]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_65]
09:21:57.261 [JavaFX Application Thread] ERROR net.straylightlabs.archivo.Archivo - ArchiveTask failed for Quantico โ Go:
net.straylightlabs.archivo.controller.ArchiveTaskException: Problem downloading recording
at net.straylightlabs.archivo.controller.ArchiveTask.handleResponse(ArchiveTask.java:266) ~[Archivo.jar:na]
at net.straylightlabs.archivo.controller.ArchiveTask.getRecording(ArchiveTask.java:162) ~[Archivo.jar:na]
at net.straylightlabs.archivo.controller.ArchiveTask.archive(ArchiveTask.java:108) ~[Archivo.jar:na]
at net.straylightlabs.archivo.controller.ArchiveTask.call(ArchiveTask.java:86) ~[Archivo.jar:na]
at net.straylightlabs.archivo.controller.ArchiveTask.call(ArchiveTask.java:59) ~[Archivo.jar:na]
at javafx.concurrent.Task$TaskCallable.call(Task.java:1423) ~[jfxrt.jar:na]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_65]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[na:1.8.0_65]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_65]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) ~[na:1.8.0_65]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) ~[na:1.8.0_65]
at java.lang.Thread.run(Thread.java:745) ~[na:1.8.0_65]
net.straylightlabs.archivo.controller.ArchiveTaskException: Problem downloading recording
at net.straylightlabs.archivo.controller.ArchiveTask.handleResponse(ArchiveTask.java:266)
at net.straylightlabs.archivo.controller.ArchiveTask.getRecording(ArchiveTask.java:162)
at net.straylightlabs.archivo.controller.ArchiveTask.archive(ArchiveTask.java:108)
at net.straylightlabs.archivo.controller.ArchiveTask.call(ArchiveTask.java:86)
at net.straylightlabs.archivo.controller.ArchiveTask.call(ArchiveTask.java:59)
at javafx.concurrent.Task$TaskCallable.call(Task.java:1423)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
09:21:57.262 [JavaFX Application Thread] INFO net.straylightlabs.archivo.Archivo - TaskStatus cleared
09:28:28.604 [JavaFX Application Thread] INFO net.straylightlabs.archivo.Archivo - Setting extension filter: Standard H.264 Files
09:28:28.608 [JavaFX Application Thread] INFO net.straylightlabs.archivo.Archivo - Last folder = /Users/rchavez/Movies/untitled folder
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1774)
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1657)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Node.fireEvent(Node.java:8411)
at javafx.scene.control.Button.fire(Button.java:185)
at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:182)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:96)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3757)
at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:352)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:275)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$355(GlassViewEventHandler.java:388)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:387)
at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
at com.sun.glass.ui.View.notifyMouse(View.java:937)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1769)
... 45 more
Caused by: java.lang.IllegalArgumentException: Folder parameter must be a valid folder
at com.sun.glass.ui.CommonDialogs.convertFolder(CommonDialogs.java:238)
at com.sun.glass.ui.CommonDialogs.showFileChooser(CommonDialogs.java:190)
at com.sun.javafx.tk.quantum.QuantumToolkit.showFileChooser(QuantumToolkit.java:1496)
at javafx.stage.FileChooser.showDialog(FileChooser.java:416)
at javafx.stage.FileChooser.showSaveDialog(FileChooser.java:392)
at net.straylightlabs.archivo.view.RecordingDetailsController.showSaveDialog(RecordingDetailsController.java:146)
at net.straylightlabs.archivo.view.RecordingDetailsController.archive(RecordingDetailsController.java:111)
... 55 more
09:28:33.587 [JavaFX Application Thread] INFO net.straylightlabs.archivo.Archivo - Setting extension filter: Standard H.264 Files
09:28:33.587 [JavaFX Application Thread] INFO net.straylightlabs.archivo.Archivo - Last folder = /Users/rchavez/Movies/untitled folder
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1774)
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1657)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Node.fireEvent(Node.java:8411)
at javafx.scene.control.Button.fire(Button.java:185)
at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:182)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:96)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3757)
at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:352)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:275)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$355(GlassViewEventHandler.java:388)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:387)
at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
at com.sun.glass.ui.View.notifyMouse(View.java:937)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1769)
... 45 more
Caused by: java.lang.IllegalArgumentException: Folder parameter must be a valid folder
at com.sun.glass.ui.CommonDialogs.convertFolder(CommonDialogs.java:238)
at com.sun.glass.ui.CommonDialogs.showFileChooser(CommonDialogs.java:190)
at com.sun.javafx.tk.quantum.QuantumToolkit.showFileChooser(QuantumToolkit.java:1496)
at javafx.stage.FileChooser.showDialog(FileChooser.java:416)
at javafx.stage.FileChooser.showSaveDialog(FileChooser.java:392)
at net.straylightlabs.archivo.view.RecordingDetailsController.showSaveDialog(RecordingDetailsController.java:146)
at net.straylightlabs.archivo.view.RecordingDetailsController.archive(RecordingDetailsController.java:111)
... 55 more
Once this happens though it seems the concept of the "Last Folder" doesn't ever get reset and it still thinks it should be pointing at "untitled folder".
Even quitting the app and restarting it doesn't fix it it seems.
From a user on tivocommunity.com: "While I currently only have a TiVo Roamio and TiVo mini connected to the LAN (returned the Bolt), I have found that upon each launch of the app it defaults to the TiVo Mini even after successfully archiving from the TiVo Roamio (last-selected). Not sure if that is because of the fix you rolled out in version 3 to handle re-scanning for TiVos when launching Archivo, but that would be my first thought."
Mac OS X 10.10.5
Put my MAK # in and the spinner stays on Looking for Tivos... I have Tivo Bolt
Any thoughts what I should try next?
Ah from the log
12:34:38.014 [pool-2-thread-1] ERROR n.s.archivo.net.TivoSearchTask - Error searching for TiVo devices:
java.io.IOException: Permission denied
at java.net.PlainDatagramSocketImpl.send(Native Method) ~[na:1.8.0_66]
at java.net.DatagramSocket.send(DatagramSocket.java:693) ~[na:1.8.0_66]
at net.straylightlabs.hola.dns.Question.askWithGroup(Question.java:114) ~[hola-0.1.2.jar:na]
at net.straylightlabs.hola.dns.Question.askOn(Question.java:105) ~[hola-0.1.2.jar:na]
at net.straylightlabs.hola.sd.Query.runOnce(Query.java:84) ~[hola-0.1.2.jar:na]
at net.straylightlabs.archivo.net.TivoSearchTask.startSearch(TivoSearchTask.java:68) [Archivo.jar:na]
at net.straylightlabs.archivo.net.TivoSearchTask.call(TivoSearchTask.java:59) [Archivo.jar:na]
at net.straylightlabs.archivo.net.TivoSearchTask.call(TivoSearchTask.java:41) [Archivo.jar:na]
at javafx.concurrent.Task$TaskCallable.call(Task.java:1423) [jfxrt.jar:na]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_66]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_66]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_66]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_66]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_66]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_66]
Some people use Archivo with TiVos that have different MAKs. Archivo should save each MAK that successfully connects to a TiVo. If the connection fails, it should cycle through each previously used MAK to see if any of them will work. If that also fails, then the user should be prompted to enter the correct MAK.
Deleting a recording may change whether a group is necessary in the recording list. When only one recording remains in the group, the group should be removed and the recording should be displayed like other non-grouped recordings.
TiVo Minis show up in the list of TiVos, but you can't archive from them because they are streaming-only devices. Since they stream from other TiVos located on the same network, we probably shouldn't display them at all.
Archivo's reconnection policy (when a TiVo returns a 502 server busy error) needs to be adjusted to match the TiVo developer documentation.
Add ability to cancel all in-progress operations.
It would be helpful if the Status column showed which recordings had been previously archived.
Add shortcut keys for common operations like archiving, refreshing, and removing a recording.
Add support for saving TiVo file metadata. This will improve the experience of playing back archived recordings via pyTivo.
When cutting commercials, the cut often begins a second or two early; just enough to feel jarring, but not enough to skip anything important.
The queue of archive tasks should allow the user to re-order recordings.
Current thought is to replace the status bar at the bottom of the window with a progress indicator in the upper-right corner. Clicking on the indicator will show a list of tasks, both queued and in-progress. Tasks will be cancelable and re-orderable directly from this list.
Evaluate whether we should use the https://bitbucket.org/infinitekind/appbundler fork of Oracle's appbundler, since it appears to be better supported.
Perhaps we should add an option to use the Video ReDo tools instead of FFmpeg and Comskip. I really want to keep Archivo as a purely open-source tool for archiving videos, but maybe this is something to consider.
The Windows installer should verify that the user is running Windows Vista or higher.
Currently, build.xml only supports building JARs for Mac OS X app bundles and Windows executables. Need to add a build target for creating a standard JAR that will easily build on Linux systems.
Multiple users have reported that Archivo hangs on the "Repairing video" step. At least one user confirmed that the problem stemmed from Avast anti-virus software. Digitally signing the ffmpeg and comskip binaries may help resolve this issue.
Users should have the option to make Archivo automatically organize archived recordings by show and season. For example, saving archiving episode 1 from season 9 of Doctor Who with this option enabled should automatically create a folder named "Doctor Show" and a folder names "Season 1" within that folder; the recording itself will be saved inside the "Season 1" folder.
Report an error to the user if we can't access a file because it's locked by another process.
Stack trace:
11:36:23.212 [pool-3-thread-1] ERROR n.s.archivo.controller.ArchiveTask - Error removing D:\Users\Todd\Videos\Tivo Exports\Masterpiece Mystery! - S07E22 - Grantchester, Episode 3.cut.ts:
java.nio.file.FileSystemException: D:\Users\Todd\Videos\Tivo Exports\Masterpiece Mystery! - S07E22 - Grantchester, Episode 3.cut.ts: The process cannot access the file because it is being used by another process.
at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:86) ~[na:1.8.0_71]
at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97) ~[na:1.8.0_71]
at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102) ~[na:1.8.0_71]
at sun.nio.fs.WindowsFileSystemProvider.implDelete(WindowsFileSystemProvider.java:269) ~[na:1.8.0_71]
at sun.nio.fs.AbstractFileSystemProvider.deleteIfExists(AbstractFileSystemProvider.java:108) ~[na:1.8.0_71]
at java.nio.file.Files.deleteIfExists(Files.java:1165) ~[na:1.8.0_71]
at net.straylightlabs.archivo.controller.ArchiveTask.lambda$cleanupFiles$10(ArchiveTask.java:653) ~[Archivo/:na]
at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948) ~[na:1.8.0_71]
at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580) ~[na:1.8.0_71]
at net.straylightlabs.archivo.controller.ArchiveTask.cleanupFiles(ArchiveTask.java:651) ~[Archivo/:na]
at net.straylightlabs.archivo.controller.ArchiveTask.cleanupFiles(ArchiveTask.java:647) ~[Archivo/:na]
at net.straylightlabs.archivo.controller.ArchiveTask.cutCommercials(ArchiveTask.java:418) ~[Archivo/:na]
at net.straylightlabs.archivo.controller.ArchiveTask.archive(ArchiveTask.java:124) ~[Archivo/:na]
at net.straylightlabs.archivo.controller.ArchiveTask.call(ArchiveTask.java:94) ~[Archivo/:na]
at net.straylightlabs.archivo.controller.ArchiveTask.call(ArchiveTask.java:61) ~[Archivo/:na]
at javafx.concurrent.Task$TaskCallable.call(Task.java:1423) ~[jfxrt.jar:na]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_71]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[na:1.8.0_71]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_71]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) ~[na:1.8.0_71]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) ~[na:1.8.0_71]
at java.lang.Thread.run(Thread.java:745) ~[na:1.8.0_71]
Add a command for opening the folder containing each recording.
Our current mDNS-SD library takes a long time (sometimes several minutes) to identify TiVo devices on the local network. It also spams the console with errors and warnings. Let's look at alternatives or potentially implement this directly in Archivo.
Archivo should be able to check for updates and alert the user.
Multiple users have reported that if a TiVo is empty, Archivo hangs at the "Looking for TiVos" step.
A user reported that Archivo keeps trying to connect to an old IP address used by their TiVo. We need to ensure we scan for TiVos at each startup and, if we find one with the same name but different IP as the last-used device, update the last-used device with the new information.
Currently, Task A must completely finish before Task B will start. We can speed things up if, after Task A has finished downloading, Task B starts downloading, but Task B won't encode until Task A has finished encoding. I.e., we should allow a queued download to proceed while Archivo is busy encoding an already-completed download.
Add a context menu to the recording list. Available options should include Archive, Cancel, Play, and Delete.
Hello, I just installed Archivo 0.2, entered my media key and now get the "Looking For Tivo's" message that doesn't go away (it's been 30 min)
I have Windows 7 64 bit, Archivo 0.2, Tivo Roamio OTR. Java 8.65 .
Log content:
22:59:34.291 [JavaFX Application Thread] INFO net.straylightlabs.archivo.Archivo - Starting up...
22:59:34.295 [JavaFX Application Thread] INFO net.straylightlabs.archivo.Archivo - Running on Java 1.8.0_65 from Oracle Corporation
22:59:34.297 [JavaFX Application Thread] INFO net.straylightlabs.archivo.Archivo - System is Windows 7 (version = 6.1, arch = x86)
23:02:46.609 [JavaFX Application Thread] INFO net.straylightlabs.archivo.Archivo - Setting status to 'Looking for TiVos...'
23:02:48.642 [pool-2-thread-1] INFO net.straylightlabs.archivo.Archivo - Found instances: []
23:02:48.738 [pool-4-thread-1] INFO net.straylightlabs.archivo.Archivo - Successfully fetched current_version.xml
23:02:48.788 [JavaFX Application Thread] INFO net.straylightlabs.archivo.Archivo - Update check: This is the latest version of Archivo (0.2 Technology Preview)
Thanks
So we know how long the recordings are :)
Detect whether the user's CPU supports Intel's Quick Sync video encoder; if so, prefer it over the software encoder.
Disable menu items that are not available based on the current context, e.g. disable Archive when the selected recording is not archivable, disable Cancel when the selected recording is not currently archiving.
Setup the File Type section of the Archive FileChooser to reflect the available encoding profiles.
Don't include the airdate in the default filenames for movies.
Confirm that the user wants to close the app if there are active archive tasks.
Add menu commands and shortcut keys for expanding or collapsing all of the groups in the recording list.
From a user:
I think I may have found a bug in the Preferences menu. When I select the "Try to remove commercials" checkbox (previously not selected) and select OK, the status of the Archivo app goes in to a loop "Looking for TiVos" and does not finish.
I can still select menu options and quit out of the app, but cannot get the new preference to save so that I can convert without commercials.
Investigate why the 'busy' cursor does not always display while fetching the recording list from TiVos.
The Windows installer leaves old JARs behind during an upgrade; it should delete old JARs instead.
All the user to create new HandBrake encoding profiles and show them in the Archive FileChooser.
Need to build binaries of ffmpeg, ffprobe, and comskip for Windows and Mac OS X systems.
The RecordingList UI should be bound to the TiVo and RecordingList model such that the entire toolbar should be disabled if no TiVos are available or if we're refreshing the recording list.
Add a "Keep until I remove" command to the File menu and context menu. It should be a toggle item that is checked when the item won't be deleted automatically and unchecked when it will be.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.