PaulLereverend / NextcloudVideo_Converter

Video converter app for nextcloud
GNU Affero General Public License v3.0
60 stars 34 forks source link

Add support for workflows #37

Open josephdpurcell opened 4 years ago

josephdpurcell commented 4 years ago

Problem / Motivation

The primary use case I have is converting proprietary codecs (e.g. videos taken on iOS devices are quicktime ".mov" files) to something more open (e.g. mp4).

I take a lot of videos and always need to convert them to an open codec. It is inefficient to have to click on each one to convert it.

Proposed Solution

Implement support for NextCloud Workflow Script. Perhaps the Automated PDF conversion extension could be used as an example? See their github project: nextcloud/workflow_pdf_converter.

josephdpurcell commented 4 years ago

I created a very basic proof of concept using ffmpeg. Here is how I set it up:

1. Install ffmpeg

sudo apt-get install ffmpeg

2. Setup the video converter script

sudo vim /usr/bin/nc_video_converter

#!/bin/bash
# Event options:
#   - \OCP\Files::postCreate
#   - OCP\SystemTag\ISystemTagObjectMapper::assignTags
# Note: assume current user is www-data
set -x

nc_event_name=$1
nc_event_type=$2
nc_src_file_path=$3
nc_user=$4
nc_src_file_name="${nc_src_file_path%.*}"
nc_src_file_extension="${nc_src_file_path##*.}"
nc_dst_file_path=$nc_src_file_name".mp4"

echo "Running converter..."
if [ "\OCP\Files::postCreate" = $nc_event_type ]
then
  echo "Checking if file has been deleted"
  if [ ! -f "/mnt/ncdata$nc_src_file_path" ]
  then
    echo "File was deleted before we could convert it"
    return 0
  fi

  echo "Checking if file is already converted"
  if [ -f "/mnt/ncdata$nc_dst_file_path" ]
  then
    echo "File is already converted. Exiting"
    return 0
  fi

  echo "Converting $nc_src_file_extension to mp4"
  ffmpeg -i "/mnt/ncdata$nc_src_file_path" -qscale 0 "/mnt/ncdata$nc_dst_file_path"
  php /var/www/nextcloud/occ files:scan "$nc_user"
fi

sudo chmod +x /usr/bin/nc_video_converter sudo chown www-data:www-data /usr/bin/nc_video_converter

3. Setup the video converter runner script

sudo vim /usr/bin/nc_video_converter_runner

#!/bin/bash

/usr/bin/nc_video_converter "$@" 2>&1 >> /var/log/nc_video_converter

sudo chmod +x /usr/bin/nc_video_converter_runner sudo chown www-data:www-data /usr/bin/nc_video_converter_runner sudo touch /var/log/nc_video_converter sudo chmod gu+w /var/log/nc_video_converter

4. Setup the workflow

  1. Login to nextcloud as an admin
  2. Go to settings -> Flow and click “Add new flow”
  3. When “File created” and “User group membership” is member of “Users”
  4. Run script: nc_video_converter_runner upload %e %n %o

Testing

To test this, take a very short video with an iOS device and upload it to nextcloud. It should be uploaded as a ".mov" file. Wait at least 5 minutes since that's who long cron takes to run. Then, you should see a ".mp4" file.

The ".mp4" file should be a lossless conversion from the ".mov" file. I did some research to confirm the right ffmpeg parameters for this, though I'm not an expert on ffmpeg so I might have something wrong there.

Interestingly, I had trouble viewing the ".mp4" file that was created in the iOS app, but was able to do so in the browser.

Next Steps

It would be great to see this concept implemented in a more robust way, or at least out of the box with Nextcloud Video Converter. Things that are missing from this concept:

josephdpurcell commented 4 years ago

Quick follow up, I've been using the above and it works very well for a proof of concept!

Does anyone have a recommendation for what should be the next step here? I'm not very familiar with the code of the nextcloud platform. Even a link to an example Workflows integration would be useful.

josephdpurcell commented 3 years ago

For NextCloud version 20.0.4 the above didn't work. Here are the scripts I'm using:

/usr/bin/nc_video_converter_runner

#!/bin/bash

echo "Running nc_video_converter..." >> /var/log/nc_video_converter
date >> /var/log/nc_video_converter
/usr/bin/nc_video_converter "$@" 2>&1 >> /var/log/nc_video_converter

/usr/bin/nc_video_converter

#!/bin/bash
# Event options:
#   - \OCP\Files::postCreate
#   - OCP\SystemTag\ISystemTagObjectMapper::assignTags
# Note: assume current user is www-data

nc_src_data_dir="/var/www/nextcloud/data"

nc_event_name=$1
nc_event_type=$2
nc_src_file_path=$3
nc_user=$4
nc_src_file_name="${nc_src_file_path%.*}"
nc_src_file_extension="${nc_src_file_path##*.}"
nc_dst_file_path=$nc_src_file_name".mp4"

echo "$nc_event_type event received..."
if [[ 'OCP\SystemTag\ISystemTagObjectMapper::assignTags' != "$nc_event_type" ]]
then
  echo "This event type is not supported: $nc_event_type"
  echo "Exiting."
  exit 0
fi

echo "Checking if file has been deleted"
if [ ! -f "$nc_src_data_dir$nc_src_file_path" ]
then
  echo "File was deleted before we could convert it"
  exit 0
fi

echo "Checking if file is already converted"
if [ -f "$nc_src_data_dir$nc_dst_file_path" ]
then
  echo "File is already converted. Exiting"
  exit 0
fi

echo "Converting $nc_src_file_extension to mp4"
if [ "debug" = $nc_event_name ]
then
  echo "DEBUG ENABLED! NOT RUNNING THE COMMAND!"
  echo "ffmpeg -i \"$nc_src_data_dir$nc_src_file_path\" -qscale 0 \"$nc_src_data_dir$nc_dst_file_path\""
  echo "php /var/www/nextcloud/occ files:scan \"$nc_user\""
else
  ffmpeg -i "$nc_src_data_dir$nc_src_file_path" -qscale 0 "$nc_src_data_dir$nc_dst_file_path"
  if [ $? -ne 0 ]
  then
    echo "Failed to convert video"
  fi
  php /var/www/nextcloud/occ files:scan "$nc_user"
fi