Giter Club home page Giter Club logo

sorry's Introduction

图片

V2EX

微信小程序试用

小程序在 2019 年因为「内容安全」被下线了,2023.4 刚申诉上线,大家可以扫码试用一下。

图片

常用特效代码

出现在句子中的特效代码会对其后的字符产生影响

咕咕{\i1}{\fs40}咕咕咕{\r}咕

示例

\n 折行
\h 空格

{\i1} 斜体
{\i0} 取消斜体

{\b1} 粗体
{\b0} 取消粗体

{\u1} 下划线
{\u0} 取消下划线

{\fs60} 调整字号

{\fad(100,200)} 100ms淡入,200ms淡出

{\r} 重置所有特效

源代码库

├── Gemfile
├── Gemfile.lock
├── LICENSE
├── public                  # 静态文件目录
├── views                   # 主页目录
├── templates               # 模板目录
├── README.md
├── site_config.yml         # 站点配置文件
├── src                     # 这里就是源代码
└── temp                    # 把临时文件安放在这里

另有

API

制作GIF:

POST https://sorry.xuty.tk/api/<template_name>/make
{
    "0": "好啊",
    "1": "...",
    ...
}

# 返回GIF下载地址
-> 200 /cache/c2f4069ed207dc38e0f2d9359a2fa6b7.gif

# 或服务器忙
-> 503

目前支持的template_name有:

- sorry
- wangjingze
- jinkela        # 金坷垃
- marmot         # 土拨鼠
- dagong         # 窃格瓦拉
- diandongche    # 窃格瓦拉偷电动车

部署指南

使用Docker

docker build -t sorry ./app
docker run --rm -it -p 4567:4567 sorry

docker-compose 一键启动

docker-compose up

手工部署

首先,机器上得安装好ruby 💎

接下来:

cd ./app

# 安装bundler
gem install bundler

# [可选] 使用国内镜像
gem sources --add https://gems.ruby-china.com/ --remove https://rubygems.org/

# [可选] Linux服务器一般需要安装中文字体
apt install ttf-wqy-microhei 

# 安装编译依赖
apt install ruby-dev build-essential

# 安装ffmpeg
apt install ffmpeg

# 安装依赖
bundle install

# 运行
ruby src/sorry.rb

# 生产环境
APP_ENV=production ruby src/sorry.rb

[可选] 使用PM2监控&自动重启

npm install pm2 -g

pm2 start process.yml --env production

# [可选] 非root用户使用80端口
sudo apt-get install authbind
sudo touch /etc/authbind/byport/80
sudo chown %user% /etc/authbind/byport/80
sudo chmod 755 /etc/authbind/byport/80

alias pm2='authbind --deep pm2'
authbind --deep pm2 update

# [可选] 定时重启服务
crontab -e
10   22  *   *   *     pm2 start sorry       

定时清除缓存

crontab -e

# 在每小时的第10分钟 清除700分钟以前的gif

10  *  *   *   *     find /root/sorry/public/cache -name '*.gif' -mmin +700  -exec rm {} \;       

添加GIF模板

向网站中添加模板需要加入以下文件

templates/<template_name>/template.mp4  # 视频模板
templates/<template_name>/template.ass  # 字幕模板
public/<template_name>/example.png   # 展示图片
views/<template_name>.erb    # 模板主页

其中index.erb 参考其他模板主页,增减<input>的数量即可

然后发个Pull request

如果你不熟悉aegisub的使用,也可以只提供视频模板。如果你是github用户,可以发个issue, 也可以发送邮件

制作字幕模板template.ass

首先使用aegisub为模板视频创建字幕,保存为template.ass(aegisub教程可以看这个 https://tieba.baidu.com/p/1360405931图片

然后把文本替换成模板字符串 <%= sentences[n] %> 图片

TODO

  • 重新设计主页
  • 重新设计404页面
  • 把gif的渲染弄成队列,提高响应速度
  • 定时删除缓存,不然有多少硬盘空间也不够用
  • 写个脚本,自动配置新的gif
  • 写测试

服务器

sorry's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sorry's Issues

关于internal server error

    /app/src/sorry/make_gif.rb:55:in `render_ass'
    /app/src/sorry/make_gif.rb:29:in `make_gif_with_ffmpeg'
    /app/src/sorry/make_gif.rb:67:in `render_gif'
    src/sorry.rb:57:in `block in <main>'

用docker容器建的,反馈中摘取这些,可能有用的信息。

求更新

什么时候能添加上那个打工的gif啊

跪求PHP版本的。

能不能更新个PHP的。比如直接装个插件上传就可以了。!!非常需求。

运行时异常

2018-02-25 01:31:36 - Errno::ENOENT - No such file or directory @ rb_sysopen - temp/197cb3a57353158ba1ca7f3f198a4ffd.gif:
        /usr/lib/ruby/2.3.0/fileutils.rb:1392:in `initialize'                                                                                                                                  
        /usr/lib/ruby/2.3.0/fileutils.rb:1392:in `open'         
        /usr/lib/ruby/2.3.0/fileutils.rb:1392:in `initialize'                                                                                                                        
        /usr/lib/ruby/2.3.0/fileutils.rb:1392:in `open'                                                                                                                                        
        /usr/lib/ruby/2.3.0/fileutils.rb:1392:in `copy_file'                                   
        /usr/lib/ruby/2.3.0/fileutils.rb:486:in `copy_file'                                    
        /usr/lib/ruby/2.3.0/fileutils.rb:403:in `block in cp'                                                                                                                                  
        /usr/lib/ruby/2.3.0/fileutils.rb:1571:in `block in fu_each_src_dest'                   
        /usr/lib/ruby/2.3.0/fileutils.rb:1585:in `fu_each_src_dest0'                           
        /usr/lib/ruby/2.3.0/fileutils.rb:1569:in `fu_each_src_dest'                                                                                                                            
        /usr/lib/ruby/2.3.0/fileutils.rb:402:in `cp'                                           
        /root/sorry_own/src/sorry/cache.rb:31:in `add_file'                                    
        /root/sorry_own/src/sorry/make_gif.rb:71:in `render_gif'                                     
        src/sorry.rb:23:in `block in <main>'                                                             
        /var/lib/gems/2.3.0/gems/sinatra-2.0.1/lib/sinatra/base.rb:1634:in `call'                   
        /var/lib/gems/2.3.0/gems/sinatra-2.0.1/lib/sinatra/base.rb:1634:in `block in compile!'                                                                                                 
        /var/lib/gems/2.3.0/gems/sinatra-2.0.1/lib/sinatra/base.rb:992:in `block (3 levels) in route!'                                                                                         
        /var/lib/gems/2.3.0/gems/sinatra-2.0.1/lib/sinatra/base.rb:1011:in `route_eval'                 
        /var/lib/gems/2.3.0/gems/sinatra-2.0.1/lib/sinatra/base.rb:992:in `block (2 levels) in route!'
        /var/lib/gems/2.3.0/gems/sinatra-2.0.1/lib/sinatra/base.rb:1039:in `block in process_route'                                                                                            
        /var/lib/gems/2.3.0/gems/sinatra-2.0.1/lib/sinatra/base.rb:1037:in `catch'             
        /var/lib/gems/2.3.0/gems/sinatra-2.0.1/lib/sinatra/base.rb:1037:in `process_route'     
        /var/lib/gems/2.3.0/gems/sinatra-2.0.1/lib/sinatra/base.rb:990:in `block in route!'    
        /var/lib/gems/2.3.0/gems/sinatra-2.0.1/lib/sinatra/base.rb:989:in `each'               
        /var/lib/gems/2.3.0/gems/sinatra-2.0.1/lib/sinatra/base.rb:989:in `route!'             
        /var/lib/gems/2.3.0/gems/sinatra-2.0.1/lib/sinatra/base.rb:1096:in `block in dispatch!'                          
        /var/lib/gems/2.3.0/gems/sinatra-2.0.1/lib/sinatra/base.rb:1075:in `block in invoke'                                                                                                   
        /var/lib/gems/2.3.0/gems/sinatra-2.0.1/lib/sinatra/base.rb:1075:in `catch'                   
        /var/lib/gems/2.3.0/gems/sinatra-2.0.1/lib/sinatra/base.rb:1075:in `block in invoke'                                                                                         
        /var/lib/gems/2.3.0/gems/sinatra-2.0.1/lib/sinatra/base.rb:1075:in `catch'                                                                                                             
        /var/lib/gems/2.3.0/gems/sinatra-2.0.1/lib/sinatra/base.rb:1075:in `invoke'            
        /var/lib/gems/2.3.0/gems/sinatra-2.0.1/lib/sinatra/base.rb:1093:in `dispatch!'         
        /var/lib/gems/2.3.0/gems/sinatra-2.0.1/lib/sinatra/base.rb:924:in `block in call!'                                                                                                     
        /var/lib/gems/2.3.0/gems/sinatra-2.0.1/lib/sinatra/base.rb:1075:in `block in invoke'   
        /var/lib/gems/2.3.0/gems/sinatra-2.0.1/lib/sinatra/base.rb:1075:in `catch'             
        /var/lib/gems/2.3.0/gems/sinatra-2.0.1/lib/sinatra/base.rb:1075:in `invoke'                                                                                                            
        /var/lib/gems/2.3.0/gems/sinatra-2.0.1/lib/sinatra/base.rb:924:in `call!'              
        /var/lib/gems/2.3.0/gems/sinatra-2.0.1/lib/sinatra/base.rb:913:in `call'               
        /var/lib/gems/2.3.0/gems/rack-protection-2.0.1/lib/rack/protection/xss_header.rb:18:in `call'
        /var/lib/gems/2.3.0/gems/rack-protection-2.0.1/lib/rack/protection/path_traversal.rb:16:in `call'
        /var/lib/gems/2.3.0/gems/rack-protection-2.0.1/lib/rack/protection/json_csrf.rb:26:in `call'
        /var/lib/gems/2.3.0/gems/rack-protection-2.0.1/lib/rack/protection/base.rb:50:in `call'                                                                                                
        /var/lib/gems/2.3.0/gems/rack-protection-2.0.1/lib/rack/protection/base.rb:50:in `call'                                                                                                
        /var/lib/gems/2.3.0/gems/rack-protection-2.0.1/lib/rack/protection/frame_options.rb:31:in `call'
        /var/lib/gems/2.3.0/gems/rack-2.0.4/lib/rack/logger.rb:15:in `call'                           
        /var/lib/gems/2.3.0/gems/rack-2.0.4/lib/rack/common_logger.rb:33:in `call'                                                                                                             
        /var/lib/gems/2.3.0/gems/sinatra-2.0.1/lib/sinatra/base.rb:231:in `call'               
        /var/lib/gems/2.3.0/gems/sinatra-2.0.1/lib/sinatra/base.rb:224:in `call'               
        /var/lib/gems/2.3.0/gems/rack-2.0.4/lib/rack/head.rb:12:in `call'                      
        /var/lib/gems/2.3.0/gems/rack-2.0.4/lib/rack/method_override.rb:22:in `call'           
        /var/lib/gems/2.3.0/gems/sinatra-2.0.1/lib/sinatra/base.rb:194:in `call'               
        /var/lib/gems/2.3.0/gems/sinatra-2.0.1/lib/sinatra/base.rb:1957:in `call'                                        
        /var/lib/gems/2.3.0/gems/sinatra-2.0.1/lib/sinatra/base.rb:1501:in `block in call'                                                                                                     
        /var/lib/gems/2.3.0/gems/sinatra-2.0.1/lib/sinatra/base.rb:1728:in `synchronize'   
        /var/lib/gems/2.3.0/gems/sinatra-2.0.1/lib/sinatra/base.rb:1501:in `block in call'                                                                                            
        /var/lib/gems/2.3.0/gems/sinatra-2.0.1/lib/sinatra/base.rb:1728:in `synchronize'                                                                                                       
        /var/lib/gems/2.3.0/gems/sinatra-2.0.1/lib/sinatra/base.rb:1501:in `call'              
        /var/lib/gems/2.3.0/gems/thin-1.7.2/lib/thin/connection.rb:86:in `block in pre_process'
        /var/lib/gems/2.3.0/gems/thin-1.7.2/lib/thin/connection.rb:84:in `catch'                                                                                                               
        /var/lib/gems/2.3.0/gems/thin-1.7.2/lib/thin/connection.rb:84:in `pre_process'         
        /var/lib/gems/2.3.0/gems/thin-1.7.2/lib/thin/connection.rb:50:in `block in process'    
        /var/lib/gems/2.3.0/gems/eventmachine-1.2.5/lib/eventmachine.rb:1076:in `block in spawn_threadpool'    

点生成无反应

按照步骤部署在自己的服务器上之后,网页显示正常,ruby src/sorry.rb运行之后在网页上操作,点生成无反应。求大佬指导,是有哪里还需要改动吗?

点击生成失败

按照教程安装所需软件,ruby,ffmpeg等,点击生成,出现如下错误

Errno::ENOENT at /sorry/make
No such file or directory @ rb_sysopen - temp/474217342e83ceb6b25573205a175529.gif
file: fileutils.rb location: initialize line: 1289
....
...

页面优化

  1. 点击生成,没有预览图。
  2. 点击下载,打开新的页面,并没有立即下载,还需要另存为。
    _meitu_0
<div id="result"> 
    <p><img src="/cache/9de545329f799d7db6b1e8cd600889b6.gif"></p>
    <p><a href="/cache/9de545329f799d7db6b1e8cd600889b6.gif" download="">点击下载</a></p>
    <p></p>
</div>

把原来的代码里的第一个 a 标签改成 img 就可以预览了。
第二个a 里面加上 download 属性,就可以直接下载了。

can not transfer gif

Errno::ENOENT at /sorry/make
No such file or directory @ rb_sysopen - temp/b244dda3e47566312e22505de0b409b8.gif

$ gem install bundler
Fetching: bundler-1.16.1.gem (100%)
Successfully installed bundler-1.16.1
Parsing documentation for bundler-1.16.1
Installing ri documentation for bundler-1.16.1
Done installing documentation for bundler after 6 seconds
1 gem installed

$ gem install ffmpeg
Fetching: ffmpeg-0.2.5.gem (100%)
Successfully installed ffmpeg-0.2.5
Parsing documentation for ffmpeg-0.2.5
Installing ri documentation for ffmpeg-0.2.5
Done installing documentation for ffmpeg after 0 seconds
1 gem installed

[fudax@fudax sorry]$ bundle install
Fetching gem metadata from https://rubygems.org/.........
Using bundler 1.16.1
Fetching daemons 1.2.6
Installing daemons 1.2.6
Fetching eventmachine 1.2.5
Installing eventmachine 1.2.5 with native extensions
Fetching mustermann 1.0.2
Installing mustermann 1.0.2
Fetching rack 2.0.4
Installing rack 2.0.4
Fetching rack-protection 2.0.1
Installing rack-protection 2.0.1
Fetching tilt 2.0.8
Installing tilt 2.0.8
Fetching sinatra 2.0.1
Installing sinatra 2.0.1
Fetching thin 1.7.2
Installing thin 1.7.2 with native extensions
Bundle complete! 2 Gemfile dependencies, 9 gems now installed.
Use bundle info [gemname] to see where a bundled gem is installed.

$ ruby src/sorry.rb
== Sinatra (v2.0.1) has taken the stage on 3389 for development with backup from Thin
Thin web server (v1.7.2 codename Bachmanity)
Maximum connections set to 1024
Listening on 0.0.0.0:3389, CTRL+C to stop

缓存问题

make请求返回请刷新或清除浏览器缓存,localStorage处理有问题

无法显示中文

不输入任何句子, 就用默认的句子, 直接点击 "生成" 按钮, 生成的.gif 能正常显示中文,

而输入中文句子, 则.gif 只能显示英文, 不能显示中文.

搭建环境: centos 7 , ruby 2.5.0 , 已安装中文包

优化gif输出画质和体积

  1. 预先计算色板,在有限的色彩空间内放下更多的使用到的颜色
  2. 减少色板数量,直接减小体积(但是色彩过渡会不自然)
  3. 优化选择画面抖动算法,使色彩过渡更加柔和

以前在windows平台下写过个类似的脚本,使用了以上提到的优化方案
https://github.com/celeron533/GIFConverter/blob/master/GIFConverter.cmd

Sample

  • fps=15
  • resolution: width=128px, height=auto
  • dither: none
  • duration: 7.5s
  • size: 541KB

Sample gif - Evangelion

https://github.com/celeron533/GIFConverter/blob/master/README.md

压缩方法

我尝试了下面的方法,对输出的 gif 进行了压缩。

对输入视频:

  • 移除 audio
  • 1.25 倍速度播放
  • resize

对生成 gif:

  • gifsicle 压缩优化

经过上面的尝试,我还是只能把 sorry 系列压缩成 1.5MB 还是略大。请问还有哪些点可以优化呢?

编码逻辑问题导致server一直显示“服务器忙!等下说不定就能用了”

def Sorry.make_gif_with_ffmpeg(template_name, sentences, filename)
	$mutex.lock
		$jobs += 1
	$mutex.unlock

# 处理代码

	$mutex.lock
		$jobs -= 1
	$mutex.unlock
end

如果在“处理代码”处抛出异常,$jobs数量就不会减1,多次抛出异常最终导致Sorry.ffmpeg_avaliablefalse

template_name是从url里获取的,只要传入一个错误的值,让Sorry.ass_text(template_name)读不到文件,即可抛出异常。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.