Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F21907208
media_helper.ex
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
3 KB
Referenced Files
None
Subscribers
None
media_helper.ex
View Options
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule
Pleroma.Helpers.MediaHelper
do
@moduledoc
"""
Handles common media-related operations.
"""
alias
Pleroma.HTTP
require
Logger
def
missing_dependencies
do
Enum
.
reduce
([
imagemagick
:
"convert"
,
ffmpeg
:
"ffmpeg"
],
[],
fn
{
sym
,
executable
},
acc
->
if
Pleroma.Utils
.
command_available?
(
executable
)
do
acc
else
[
sym
|
acc
]
end
end
)
end
def
image_resize
(
url
,
options
)
do
with
executable
when
is_binary
(
executable
)
<-
System
.
find_executable
(
"convert"
),
{
:ok
,
args
}
<-
prepare_image_resize_args
(
options
),
{
:ok
,
env
}
<-
HTTP
.
get
(
url
,
[],
pool
:
:media
),
{
:ok
,
fifo_path
}
<-
mkfifo
()
do
args
=
List
.
flatten
([
fifo_path
,
args
])
run_fifo
(
fifo_path
,
env
,
executable
,
args
)
else
nil
->
{
:error
,
{
:convert
,
:command_not_found
}}
{
:error
,
_
}
=
error
->
error
end
end
defp
prepare_image_resize_args
(
%{
max_width
:
max_width
,
max_height
:
max_height
,
format
:
"png"
}
=
options
)
do
quality
=
options
[
:quality
]
||
85
resize
=
Enum
.
join
([
max_width
,
"x"
,
max_height
,
">"
])
args
=
[
"-resize"
,
resize
,
"-quality"
,
to_string
(
quality
),
"png:-"
]
{
:ok
,
args
}
end
defp
prepare_image_resize_args
(%{
max_width
:
max_width
,
max_height
:
max_height
}
=
options
)
do
quality
=
options
[
:quality
]
||
85
resize
=
Enum
.
join
([
max_width
,
"x"
,
max_height
,
">"
])
args
=
[
"-interlace"
,
"Plane"
,
"-resize"
,
resize
,
"-quality"
,
to_string
(
quality
),
"jpg:-"
]
{
:ok
,
args
}
end
defp
prepare_image_resize_args
(
_
),
do
:
{
:error
,
:missing_options
}
# Note: video thumbnail is intentionally not resized (always has original dimensions)
def
video_framegrab
(
url
)
do
with
executable
when
is_binary
(
executable
)
<-
System
.
find_executable
(
"ffmpeg"
),
{
:ok
,
env
}
<-
HTTP
.
get
(
url
,
[],
pool
:
:media
),
{
:ok
,
fifo_path
}
<-
mkfifo
(),
args
=
[
"-y"
,
"-i"
,
fifo_path
,
"-vframes"
,
"1"
,
"-f"
,
"mjpeg"
,
"-loglevel"
,
"error"
,
"-"
]
do
run_fifo
(
fifo_path
,
env
,
executable
,
args
)
else
nil
->
{
:error
,
{
:ffmpeg
,
:command_not_found
}}
{
:error
,
_
}
=
error
->
error
end
end
defp
run_fifo
(
fifo_path
,
env
,
executable
,
args
)
do
pid
=
Port
.
open
({
:spawn_executable
,
executable
},
[
:use_stdio
,
:stream
,
:exit_status
,
:binary
,
args
:
args
])
fifo
=
Port
.
open
(
to_charlist
(
fifo_path
),
[
:eof
,
:binary
,
:stream
,
:out
])
fix
=
Pleroma.Helpers.QtFastStart
.
fix
(
env
.
body
)
true
=
Port
.
command
(
fifo
,
fix
)
:erlang
.
port_close
(
fifo
)
loop_recv
(
pid
)
after
File
.
rm
(
fifo_path
)
end
defp
mkfifo
do
path
=
Path
.
join
(
System
.
tmp_dir!
(),
"pleroma-media-preview-pipe-
#{
Ecto.UUID
.
generate
()
}
"
)
case
System
.
cmd
(
"mkfifo"
,
[
path
])
do
{
_
,
0
}
->
spawn
(
fifo_guard
(
path
))
{
:ok
,
path
}
{
_
,
err
}
->
{
:error
,
{
:fifo_failed
,
err
}}
end
end
defp
fifo_guard
(
path
)
do
pid
=
self
()
fn
->
ref
=
Process
.
monitor
(
pid
)
receive
do
{
:DOWN
,
^
ref
,
:process
,
^
pid
,
_
}
->
File
.
rm
(
path
)
end
end
end
defp
loop_recv
(
pid
)
do
loop_recv
(
pid
,
<<>>)
end
defp
loop_recv
(
pid
,
acc
)
do
receive
do
{
^
pid
,
{
:data
,
data
}}
->
loop_recv
(
pid
,
acc
<>
data
)
{
^
pid
,
{
:exit_status
,
0
}}
->
{
:ok
,
acc
}
{
^
pid
,
{
:exit_status
,
status
}}
->
{
:error
,
status
}
after
5000
->
:erlang
.
port_close
(
pid
)
{
:error
,
:timeout
}
end
end
end
File Metadata
Details
Attached
Mime Type
text/x-ruby
Expires
Sun, Dec 28, 1:41 AM (12 h, 37 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
796063
Default Alt Text
media_helper.ex (3 KB)
Attached To
Mode
rPUBE pleroma-upstream
Attached
Detach File
Event Timeline
Log In to Comment